EDN首页   博客首页

1

关于投票
PIC18F系列读写FLASH的函数

网上搜了一下,关于PIC18F系列读写FLASH的函数,有很多都是有错误的或者有BUG的,集中在表指针的操作上.

 

因此走了些弯路,现在发一个我自己写的读写FLASH的函数分享给大家,已测试过,支持绝大部分PIC18F系列的芯片.

 

还有一个是写"1字节"的函数,写几个字节的时候很有用.有人一定会反驳说写操作不是按64个字节块来执行的吗?确实是,下边已经给出注释了.

 

以下是写函数的部分代码:

#define addr 0x400   //定义要写入的起始地址

//写周期
void Write_Cycle(void)
{
 EEPGD = 1;    //EEPGD:闪存程序存储器或数据EEPROM 选择位
                         //1 = 访问闪速程序存储器
                         //0 = 访问数据EEPROM
 CFGS = 0;      //CFGS:闪存程序存储器/ 数据EEPROM 或配置寄存器选择位
                         //1 = 访问配置寄存器
                         //0 = 访问闪存程序存储器或数据EEPROM
 WREN = 1;    //WREN:闪存程序/ 数据EEPROM 写使能位
                         //1 = 允许闪存程序/ 数据EEPROM 的写周期
                         //0 = 禁止闪存程序/ 数据EEPROM 的写周期
 CARRY = 0;
 if(GIE)
    CARRY = 1;
 GIE = 0;         //关全局中断
 EECON2 = 0X55;
 EECON2 = 0XAA;
 WR = 1;        //1 启动读/写周期;0 写周期完成
 NOP();
 NOP();
 while(WR) ;  //等待写周期完成
 WREN = 0;    //0 禁止向程序存储器或EEPROM写操作

 if(CARRY)
      GIE = 1;     //IPEN=1,开中断
}

//器件复位时和写操作后保持寄存器的默认
//值为FFh。向保持寄存器写入FFh 并不会
//修改寄存器中存储的字节。这意味着,假如
//不想将某个位从0 改为1,而仅修改程序存
//储器中的个别字节也是可以的。当修改个
//别字节时,在执行写操作前不必装入所有
//的64 个保持寄存器。

 

//写函数,每次写入FLASH是1个字节
void Write_One_Byte(unsigned long address,unsigned char data)
{
     TBLPTRL = ((address) & 0xFF);
     TBLPTRH = (((address) >> 8) & 0xFF);
     TBLPTRU = (((address) >> 8) >> 8);

    TABLAT = data;
    asm("\tTBLWT*");

    FREE = 0;          //只执行写操作
    Write_Cycle();
}

//写函数,每次写入FLASH只能是64字节,故要写入大量数据的话,就需要多次写入
void Flash_Write(unsigned long address,unsigned char *Pdata)
{
 unsigned char count;
 unsigned char length; 

 Flash_Erase(address);     //擦除64个字节

 for(count=0; count<8; count++)    //写8次,8*8=64
 {
      TBLPTRL = ((address+count*8) & 0xFF);  //地址载入TBLPTR
      TBLPTRH = (((address+count*8) >> 8) & 0xFF);
      TBLPTRU = (((address+count*8) >> 8) >> 8);

  for(length=0; length<8; length++)    //写8字节到RAM
  {
     TABLAT = *(Pdata+length+count*8); //数据载入TABLAT
     if(length != 0)     
    {
        asm("\tTBLWT+*");  //TBLPTR需要预先增加   
     }
     else
     {
       asm("\tTBLWT*");  //地址已经载入TBLPTR,不需要预先增加   
      }
   }

    FREE = 0;       //只执行写操作
    Write_Cycle();
 }
}

void main(void)
{   
 Write_One_Byte(addr-1, 0xaa);
 Flash_Write(addr, &data[0]);
 while(1)
 {
  temp = Flash_Read(addr-1);
 }
}

 

MPLAB SIM仿真结果,其中地址0x3ff中的数据:0xaa就是用"写1字节"函数写上去的.

 

附件内含两个工程,一个是用PICC18编译器的,一个是MCC18编译器的.

 

再送大家一个CleanUp.bat,可以用来清除编译器产生的一些链接文件之类的,很好用.

附件下载地址:点击下载

系统分类: 单片机
用户分类: PIC单片机
标签: PIC FLASH
来源: 原创
发表评论 阅读全文(216) | 回复(0)

1

关于投票
如何把两个*.hex合并成一个*.hex?在写IAP/Bootloader很有用哦

        前几天,一网友在某论坛上问我关于PIC Bootloader的问题,他问如何创建两个工程分别编写引导程序和用户程序,分别将两个工程编译成两个.hex文件,然后手工合为一个.hex文件,然后再把这个合并后的.hex文件(即包含引导程序和用户程序)烧写到芯片上去?

 

        恰好在这之前我写过PIC Bootloader,遇到并解决了这个问题.那么现在就来向大家介绍一下关于如何把两个.hex文件合并成一个.hex的方法,一般在你写IAP/Bootloader的时候能够用到,此方法自己认为很有创造性,希望大家喜欢,呵呵.

 

        阅读此文章之前你需要了解如下几个方面的知识:
        1.如何在PICC18编译器中实现程序定位?
答:方法是在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量XXX(注意这里输入的已经是16进制了,不用在转换)。 
        重新编译,然后在View->Program Memory就可以看到你的程序已经定位在XXX起始的地址上了.
        2.理解这个语句所代表的意思:  (*((void(*)(void))User_Start))();
        3.了解hex文件的格式.

 

        好,现在就开始谈谈实现方法吧:
        1.配置,编译,链接第一个程序,生成第一个.hex文件
        下边这个程序是0ffset_0x000.c,其代码位于0x000-0x4ff起始的地址块上,请参照Note上的提示进行设置,把生成的hex文件命名为:000.hex
/************************************************************************************************
**本程序只供学习使用,未经作者许可,不得用于其它任何用途
**版权所有,盗版必究。
**Copyright(C) CheungMan
**All rights reserved
**欢迎访问我的blog:http://www.ednchina.com/blog/cheungman
**E-mail          : zhw-198@163.com
************************************************************************************************
**FileName      : 0ffset_0x000.c
**Target        : PIC18F458
**XTAL          : 4MHZ
**Autor         : ZhangWen
**Start Date    : 2008.04.24
**Modify Date   :
**Edition       : V1.0
**HardWare      :
**SofeWare      : MPLAB IDE v8.02 + PICC 18 v8.35
**Function      : 请在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,
**    在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量0
**Note          : 注意,此程序偏移0x000地址,其实默认就是0.
***********************************************************************************************/

#include

__CONFIG(1, HSPLL);   //配置HS,4倍频
__CONFIG(2, WDTDIS);   //禁止看门狗

#define User_Start    0x500     //用户程序开始位置

//延时
void Delay(void)
{
 unsigned long i;
 for(i=0; i<150000; i++);
}

void main(void)
{
 unsigned char FlashTime; //定义闪烁次数
     TRISB = 0x00;   //定义RB0-RB7为输出   
     PORTB = 0x00;   //初始化为低电平
     while(1)
    {
         for(FlashTime=0; FlashTime<10; FlashTime++)//闪烁10次
  {
   PORTB = 0xff;
          Delay();
          PORTB = 0x00;
          Delay();
  }
         (*((void(*)(void))User_Start))(); //进入用户程序,即0x500地址起始的程序代码,也就是0ffset_0x500.c
    } 
}

         2.配置,编译,链接第二个程序,生成第二个.hex文件
        下边这个程序是0ffset_0x500.c,其代码位于0x500-0xXXX起始的地址块上,请参照Note上的提示进行设置,把生成的hex文件命名为:500.hex
/************************************************************************************************
**本程序只供学习使用,未经作者许可,不得用于其它任何用途
**版权所有,盗版必究。
**Copyright(C) CheungMan
**All rights reserved
**欢迎访问我的blog:http://www.ednchina.com/blog/cheungman
**E-mail          : zhw-198@163.com
************************************************************************************************
**FileName      : 0ffset_0x500.c
**Target        : PIC18F458
**XTAL          : 4MHZ
**Autor         : ZhangWen
**Start Date    : 2008.04.24
**Modify Date   :
**Edition       : V1.0
**HardWare      :
**SofeWare      : MPLAB IDE v8.02 + PICC 18 v8.35
**Function      : 请在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,
**    在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量0x500
**Note          : 注意,此程序偏移0x500地址
***********************************************************************************************/

#include

__CONFIG(1, HSPLL);     //配置HS,4倍频
__CONFIG(2, WDTDIS);    //禁止看门狗

//延时
void Delay(void)
{
 unsigned long i;
 for(i=0; i<150000; i++);
}

void main(void)
{
    TRISB = 0x00; //定义RB0-RB7为输出 
    PORTB = 0x00; //初始化为低电平
    while(1)
    {
 PORTB = 0xaa;
        Delay();
        PORTB = 0x55;
        Delay();
    } 
}

        3.使用UltraEdit分别打开000.hex和500.hex,然后对比一下两者,把500.hex中的部分代码复制并插入到000.hex的代码中,请看图1和图2所示,然后再另存为test.hex.至于为什么要这样操作或者怎样操作,请了解hex的格式先吧.

点击看大图

                                                     图1.选取500.hex上的数据

点击看大图

                                                   图2.拷贝到000.hex上去

        4.接着你可以把这个新生成的test.hex通过ICD2直接下载到芯片上去,你就可以看到0ffset_0x000.c程序中描述的,看到所有RB0-RB7闪烁10次后,接着就会进入0ffset_0x500.c程序中描述的,RB0-RB7间隔闪烁.如果在0ffset_0x500.c程序上再跳转到0x000地址上去的话,又运行0ffset_0x000.c程序了,是不是很有意思啊?不过我没增加这样的语句,你们自己加加看.

        5.在这里,我就用PROTEUS调试给大家看看吧,请看图3和图4.

                                 图3.运行0ffset_0x000.c时的情况

                          图4.运行0ffset_0x500.c时的情况

        PS:在这里要注意的是0ffset_0x500.c,由于此程序已偏移到0x500地址上去,如果你编写含中断的程序的话,需要重定义中断向量.至于如何重定义,下次再写篇如何定义的博文吧.这里我就没有重定义中断向量了,为的是用最简单,最通俗的程序,让大家理解,明白.
    
        再PS:请严格按照程序中NOTE的指示进行设置.

源码:rar

系统分类: 单片机
用户分类: PIC单片机
标签: PIC IAP BOOTLOADER HEX
来源: 原创
发表评论 阅读全文(938) | 回复(1)

1

关于投票
如何使用PIC C30中的外设库函数?

        刚开始学dsPIC33,发现MicroChip做的C30编译器还不错,里边有常用的外设库(Peripheral Libraries),写程序也不用查datasheet就可以很快配置好寄存器了,节省了时间。


        由于刚上手MPLAB,根据前段时间对PIC32中的C32的了解,并根据C:\Program Files\Microchip\MPLAB C30\docs\中相关文档的学习,开始使用C30中的外设库编程。但是每次MAKE PROJECE的时候,老是出错,发现老是提示错误说LINK STEP ERROR。根据对编译器的一知半解,知道是库文件上出了问题,把C30目录下的文档翻了一遍,也没看到相关SAMPLE,看了HELP也没发现有什么要注意的地方,把BUILD OPTIONS中的选项仔细配置一下也仍失败。


        经过baidu,发现国内PIC 16位单片机的讨论和资料都很少。去MicroChip官方网站浏览了一下,发现SAMPLE也很少提及。无奈之下去MicroChip BBS上求救,经历第一次用蹩脚的英语在外国论坛上跟人家交流。


        后来一瑞典的外国网友指出“I think you need to include the .coff file for your device in the Library folder of your Mplab project tree ”。


        当时也不知道如何解决,后来看了C:\Program Files\Microchip\MPLAB C30\docs\periph_lib\16-bit Peripheral Libraries.htm中其中一段话
      “The library files are of the form libpDevice-elf.a or libpDevice-coff.a (depending on executable/object file format selected during the compile operation), where Device is a 16-bit device number (e.g., libp24HJ256GP610-coff.a or libp24HJ256GP610-elf.a for the PIC24HJ256GP610 device). ”


    我明白问题怎样解决了,于是我在MPLAB项目树中的Library Files中添加了libp33FJ64GP710-coff.a文件,再次MAKE,终于提示BUILDE SUCCEEDED。

点击看大图

e44fe62c

系统分类: 单片机
用户分类: PIC单片机
标签: PIC 16 dsPIC33 单片机
来源: 原创
发表评论 阅读全文(472) | 回复(0)
总共 , 当前 /