0 天梯 之 从零开始玩转PIC - 第8页 - Microchip论坛 - PIC单片机论坛 - Microchip(微芯科技)MCU官方技术支持论坛 - 21ic电子技术开发论坛
打印
[PIC®/AVR®/dsPIC®产品]

天梯 之 从零开始玩转PIC

[复制链接]
楼主: 程序匠人
手机看帖
扫描二维码
随时随地手机跟帖
141
niu9911| | 2008-2-14 12:22 | 只看该作者 回帖奖励 |倒序浏览

将单文件系统改为多文件系统

请教一下,将单文件系统改为多文件系统时,如果有表格(比如说LCD的显示内容表在多个C中都用到了)是应该怎么处理才能通过编译?

使用特权

评论回复
142
hotpower| | 2008-2-14 12:24 | 只看该作者

87X好象没有自带固化的BOOTLOAD

使用特权

评论回复
143
程序匠人|  楼主 | 2008-2-14 12:30 | 只看该作者

严格意义上来说,匠人不是想做IAP

而是想通过串口来修改程序空间里的表格内容。由于这些表格也是放在FLASH中,因此,匠人想原理应该和IAP差不多吧。

只是,C编译器里,如何确定表格的地址呢?

使用特权

评论回复
144
程序匠人|  楼主 | 2008-2-14 12:55 | 只看该作者

niu9911 的问题匠人也感兴趣

匠人不喜欢在多个模块(文件)中处理显示。那好像有违模块化编程的精神。所以没有遇到过你的困扰。不过,匠人对这个问题也感兴趣。


——————————————————————————————

niu9911 发表于 2008-2-14 12:22 PIC 单片机 ←返回版面    

148楼: 将单文件系统改为多文件系统 

请教一下,将单文件系统改为多文件系统时,如果有表格(比如说LCD的显示内容表在多个C中都用到了)是应该怎么处理才能通过编译?

 
 

使用特权

评论回复
145
niu9911| | 2008-2-14 17:54 | 只看该作者

请教匠人

我有五个模块:AD,EE,LCD,KEY和MAIN,其中KEY是个LCD的显示菜单屏,要用到表格,MAIN中在循环中也要显示正常数据用到表格,LCD中就不要说了,匠人说有违模块化编程的精神,那我应该怎么做这几个模块。
用的是C30,在现在的程序中我把LCD的表格和函数定义及函数都放到LCD.H中,在MAIN和KEY中都#INCLUDE LCD.H,程序还是能编译的。但把函数定义放在LCD.H中,把函数放在LCD.C中,表格不知道怎么放了。请教别人说把表格放MAIN中,可试试还是不成。

使用特权

评论回复
146
程序匠人|  楼主 | 2008-2-14 19:05 | 只看该作者

回niu9911

匠人一般不会在显示模块之外做查表送显的动作。
按键模块只执行按键的监测和功能解析;main()中就更不会去做任何实际功能了。
模块化编程,就是各司其职。相互通过变量传递信息就好了。

//--------------------------------------------------------
//主函数
//--------------------------------------------------------
void main(void)
{
    init();                        //====初始化

    //====循环主体
    while (1)
    {
        asm ("clrwdt");                    //喂狗
        //asm ("nop");
    
    
        //
        if ( T_10MS_FLAG ) time_cnt() ;                //如果10毫秒定时溢出标志=1,则调用计时处理程序
        if ( NEW_DISP_EN_FLAG )    new_display() ;            //如果显示刷新使能标志=1,则刷新显示缓冲区
    
        if ( ADGO == 0 ) adc_cnt() ;                //如果ADC结束,则调用ADC处理程序
        if ( TEMP_SCAN_EN_FLAG ) temp_cnt() ;              //如果温度检测使能标志=1,则调用温度处理程序
        
        comm_cnt();                        //串行通讯后台处理
        
        if ( (EEPROM_NEW_FLAGS!=0) && (WR==0) && (NO_KEY_JSQ>5) ) new_eeprom() ;    //如果EEPROM数据更新标志<>0,且写操作结束,且无按键计数器>5,则更新eeprom内容

    }
}

使用特权

评论回复
147
hotpower| | 2008-2-14 19:39 | 只看该作者

有点不是问题的问题~~

if ( T_10MS_FLAG ) time_cnt() ;

应该为:
if ( T_10MS_FLAG ) 
{
  time_cnt() ;
  T_10MS_FLAG = 0;
}

总不至于:
void time_cnt(void) 
{
//..........
  T_10MS_FLAG = 0;
}

使用特权

评论回复
148
yewuyi| | 2008-2-15 08:51 | 只看该作者

niu9911用extern不就可以了吗?

87X没有固化的BOOTLOAD,需要自己写。


‘表格的地址怎么确定’好象不是什么大问题把?

不能取得地址的话,你定的表格怎么查啊?!


如果你只是想修改一下表格的话,其实很好办啊,不需要什么BOOTLOAD:
1:程序中定义一个数组,用它存你的表格,这个数组可以在EE/FLASH/RAM中
   估计你的表格不能放在RAM中,那只能是EE和FLASH了
2:UART接受表格数据和表格地址,并把接受到的数据按照接受到的表格地址
   写入EE或FLASH中
3:写EE和FLASH的代码你自己已经在上面整出来了
4:程序中一定要防止写FLASH越界,否则把CHIP中代码冲掉了可和我没关系,呵呵,俺建议你还是放EE中把~~

使用特权

评论回复
149
程序匠人|  楼主 | 2008-2-15 09:53 | 只看该作者

回hotpower

匠人喜欢这样写:

void time_cnt(void) 
{
  T_10MS_FLAG = 0;
//..........
}

使能标志位的清零动作,匠人喜欢放在子程序(子函数)内部,当然这只是习惯问题。编译出来的代码效率应该是一样的吧。有问题吗?

--------------------------------------------
hotpower 发表于 2008-2-14 19:39 PIC 单片机 ←返回版面    

154楼: 有点不是问题的问题~~ 

if ( T_10MS_FLAG ) time_cnt() ;

应该为:
if ( T_10MS_FLAG ) 
{
  time_cnt() ;
  T_10MS_FLAG = 0;
}

总不至于:
void time_cnt(void) 
{
//..........
  T_10MS_FLAG = 0;
}
 
 

使用特权

评论回复
150
程序匠人|  楼主 | 2008-2-15 10:16 | 只看该作者

回yewuyi


说明几点:
1、表格内容是显示点阵图片(每一帧需要180个字节)。匠人目前还有空余空间约6k,想全部用来做点阵图片。并且希望这些图片可通过串口来修改。eeprom中只有256个单元。因此,必须放在flash中。

2、PICC是自动分配程序的地址空间的,而我们读写FLASH时必须有明确的地址。这就是匠人的困扰所在。也就是说,默认的图片内容存放地址与程序运行时读写该图片存放地址如何统一?




----------------------------------------
 yewuyi 发表于 2008-2-15 08:51 PIC 单片机 ←返回版面    

155楼: niu9911用extern不就可以了吗? 

87X没有固化的BOOTLOAD,需要自己写。


‘表格的地址怎么确定’好象不是什么大问题把?

不能取得地址的话,你定的表格怎么查啊?!


如果你只是想修改一下表格的话,其实很好办啊,不需要什么BOOTLOAD:
1:程序中定义一个数组,用它存你的表格,这个数组可以在EE/FLASH/RAM中
   估计你的表格不能放在RAM中,那只能是EE和FLASH了
2:UART接受表格数据和表格地址,并把接受到的数据按照接受到的表格地址
   写入EE或FLASH中
3:写EE和FLASH的代码你自己已经在上面整出来了
4:程序中一定要防止写FLASH越界,否则把CHIP中代码冲掉了可和我没关系,呵呵,俺建议你还是放EE中把~~
 
 

使用特权

评论回复
151
martin| | 2008-2-15 12:50 | 只看该作者

匠人不要困扰,不能绝对定位,但可以绝对避开

PICC是不可以对程序或数据绝对定位的,但是编译器有命令行选项来让编译器绝对避开某些区域。
避开的方法是,在Build options窗口中的PICC Compiler和PICC Linker的命令行选项中加入:
--ROM=0-XXX
例如,要避开16F877程序末尾的512个字,可以
--ROM=0-1E00
当然,还可以避开程序中间的某个区域,具体请参看PICC Maunal里的--ROM命令行说明。

避开了某个区域,这个区域的地址范围是绝对的。
Flash的读,写,擦除都是可以绝对地址定位的。
那么,程序就可以对这个避开区域的地址范围进行Flash数据读写擦除操作了。

但是,有一个问题,就是这个区域的数据不能在芯片烧录时就写进初始化数据(因为编译器产生的HEX已经完全避开了这个FLash数据区)。不过匠人已经写了串口下载程序,那么就等芯片烧录好了之后,用串口接收然后写进这个区域就好了。

注:--ROM命令行本人在PICC 9.60上测试过,不确定低版本的PICC是否可行。

使用特权

评论回复
152
程序匠人|  楼主 | 2008-2-15 12:54 | 只看该作者

送martin一条裤子先

回头去试试看。不过正如你所说的,问题似乎没有圆满解决。

“但是,有一个问题,就是这个区域的数据不能在芯片烧录时就写进初始化数据(因为编译器产生的HEX已经完全避开了这个FLash数据区)。”

使用特权

评论回复
153
yewuyi| | 2008-2-16 08:45 | 只看该作者

虽然使用绝对定位有一定风险

但PICC编译的时候,代码都是按照低地址向高生长的,所以你把表格地址绝对定位到后面的剩余ROM区也未尝不可,但前提是,你应该对你的代码大小有预编译(去掉表格),PICC会告诉你的代码编译后的大小,你把表格的地址放到这个代码空间之后就可以。

惟一需要注意的就是:PICC不会做ROM重叠报错,你一定需要人工防止编译重叠,但IAR的PIC编译器听说是可以的,但IAR FOR PIC俺没用过。


另:你通过UART发送数据,但不发送实际表格地址,只发送表格的序号,然后通过你MCU内部的代码来取得表格的ROM地址,难道这样也不可以?

使用特权

评论回复
154
程序匠人|  楼主 | 2008-2-16 11:45 | 只看该作者

绝对定位 如何实现?

使用特权

评论回复
155
pcbomb| | 2008-2-16 23:33 | 只看该作者

我最近也在学PIC单片机

用ICD2的时候发现可以下载程序但不能单步DEBUG,很是郁闷
提示ICD0083: Debug:  Unable to enter debug mode.  Please double click this message for more information.

使用特权

评论回复
156
pcbomb| | 2008-2-16 23:36 | 只看该作者

先用定时器0中断做一个时钟中断程序

用一个IO控制一个LED闪烁时发现个问题,PICC是不是不支持这样写:RC1=!RC

使用特权

评论回复
157
pcbomb| | 2008-2-16 23:37 | 只看该作者

程序

#include    <pic.h>


//定义芯片工作时的配置位
//__CONFIG(HS & WDTDIS & PWRTEN & BOREN & DP & LVPDIS & DUNPROT & WRTDIS & DEBUGEN & UNPROTECT);
__CONFIG(INTIO & WDTDIS  & PWRTDIS &MCLREN & UNPROTECT &OSC_4MHZ &BORDIS);

//定义变量
unsigned char i;

void interrupt ISR(void)
{
    TMR0=6;
    T0IF=0;    //清除TMR0 中断标志
    i++;
}

//声明函数类型
void    timer0_init(void)
{
    T0CS=0;            //使用内部时钟周期
    PSA=0;            //预分频给TIME0                                                                                       
//时钟源=4MHZ,指令周期=1us,设Timer0的预分频系数是1:256,TMR0的初值是6,定时时间:256×(256-6)×1us=64ms 
    PS0=1;            //TIME0预分频=1:256
    PS1=1;    
    PS2=1;    
    
    T0IF=0;            //TIME0中断溢出标志=0
    T0IE=1;            //允许TIME0中断
}

void    main(void)
{
    TRISC=0x00;
    timer0_init();    
    GIE=1;            //允许所有中断
    TMR0=6;            //TMR0的初值=6
while(1)
    {
        if(i==10)
            {
                i=0;
                RC1=!RC1;
            }
    }
}

使用特权

评论回复
158
pcbomb| | 2008-2-16 23:45 | 只看该作者

然后改成这样才好了

void    main(void)
{
    TRISC=0x00;
    timer0_init();    
    GIE=1;            //允许所有中断
    TMR0=6;            //TMR0的初值=6
while(1)
    {
        if(i==10)
            {
                i=0;
                PORTC=PORTC>>1;
            if(PORTC==0)
                {
                    PORTC=170;
                }
            }
    }
}

使用特权

评论回复
159
ayl439| | 2008-2-29 22:14 | 只看该作者

刚接触了一点pic

可惜没有开发板,暂时也没有用这个的项目。

使用特权

评论回复
160
iQanalog| | 2010-1-18 02:31 | 只看该作者
受骗的感觉

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则