PIC12F675 单片机内存不足怎么办

[复制链接]
 楼主| lvsezhidu 发表于 2025-3-22 21:29 | 显示全部楼层 |阅读模式
笔者弄2路AD转换,采用2只74ls164驱动8只集成数码管显示2路AD转换结果,但提示内存不足,编译不通过,不知怎么办?Error   [1360] D:\desktop\PIC12F675_gai\main.c; 181. no space for auto/param AD_TMR0_ISR@Result_170

  1. #include <pic.h>   //PIC12F675
  2. //__CONFIG(0x2004);      //?????? //配置字要在头文件后 PROTEUS仿真也要有  PIC12F675/629 手册9.1配置位P54
  3. //bit13/12BG1:0=00最低/11最高带隙电压  bit11:9空  bit8 CPD=0使能/1禁止RAM保护
  4. //bit7 CP=0使能/1禁止ROM保护bit6=1使能/0禁止欠压检测  bit5  MCLR=0/1GP3复位脚/GP3数字脚,内部复位
  5. //bit4 PWRET使能上电延时定时器1=禁止,0=使能 bit3 看门狗使能位1=使能,0=禁止     手册14.1配置位
  6. //bit2:0 FOSC2:0振荡器使能100=INTOSC振荡,GP4/GP5数字I/O口

  7. #define  _XTAL_FREQ 4000000UL

  8. #define INT8U   unsigned char
  9. #define INT16U  unsigned int

  10. #define DAT GPIO2   //74LS164串行数据线
  11. #define CLK GPIO3  //74LS164串行时钟线
  12. #define RST GPIO4  //74LS164复位脚

  13. //共阳数码管0~9的数字段码,最后一位为黑屏
  14. const INT8U SEG_CODE[11] ={0xC0,0xF9,0xA4,0xB0,0x99,
  15.                          0x92,0x82,0xF8,0x80,0x90,0xFF};
  16. //两路模拟转换结果显示缓冲,显示格式为:X.XX X.XX ,第4位和第8位不显示
  17. //volatile INT8U Display_Buffer[8] = {0,0,0,10,0,0,0,10};
  18. volatile INT8U k = 0, j = 0;
  19. volatile int Result = 0;
  20. //==================================================
  21. void ADC_int(void);            //ADC模块初始化
  22. void Serial_Output(INT8U d);   // 模拟时序向74HC164串行输出1字节数据

  23. //-----------------------------------------------------------------
  24. // 模拟时序向74HC164串行输出1字节数据
  25. //-----------------------------------------------------------------
  26. void Serial_Output(INT8U d)
  27. {
  28.         INT8U i;  
  29.         for(i = 0; i < 8; i++)                   //1个字节8位
  30.         {
  31.           CLK = 0;                                            //时钟置0
  32.           if(d&0x80)DAT = 1;                   //移出一位(高位优先)
  33.       else DAT = 0;
  34.       d <<= 1;
  35.           CLK = 1;                                           //时钟置1,上升沿数据移入74HC164
  36.         }
  37. }

  38. void ADC_int(void)
  39. {
  40.     //手册P46 ANSEL - ADCS2 ADCS1 ADCS0 ANS3:0
  41.     //        ADCS2=0;ADCS1=1;ADCS0=0;        //FOSC/32       
  42.     //ANS1=1;ANS0=1;                   //AN0/AN1模拟输入
  43.     ANSEL = 0b10100011;

  44.    //手册P45 ADCON0  ADFM VCFG - - CHS1 CHS0 GO/DONE ADON
  45.         //ADFM=1;          //1右对齐
  46.     //VCFG=0;          //VDD参考电压,1=VREF参考电压
  47.     //CHS1=0;CHS0=0;   //通道0
  48.     //GODONE = 1;                          //启动AD转换
  49.     ADCON0 = 0b10110010;
  50.     __delay_ms(2000);       //启动AD转换后要延时,等待AD模块稳定

  51.     PIE1 |= 0b01000000;      //ADIE = 1;       //使能AD转换中断
  52.     PIR1 &= 0b10111111;   //ADIF= 0;    //AD转换中断标志清0

  53. }

  54. void main(void)
  55. {
  56.         //TRISIO2=0;TRISIO3=0;TRISIO4=0;
  57.     TRISIO = 0b00000011;
  58.     GPIO2=1;GPIO3=1;GPIO4=1;
  59.    //以下配置用于TMR0定时器刷新数码管显示
  60.     PSA = 0;                                //前分频给TMR0
  61.         PS2 = 0; PS1 = PS0 = 1;                 //16分频(OPTION低3位为011)
  62.         TMR0 = (INT8U)(256 - _XTAL_FREQ / 4 / 16 * 0.002); //2ms定时
  63.         T0IF = 0;                               //清TMR0中断标志
  64.         T0CS = 0;                               //TMR0内部指令周期,工作于定时器
  65.         T0IE = 1;                               //允许TMR0溢出中断

  66.     PEIE = 1;                           //允许所有的未屏蔽的中断
  67.     GIE = 1;                            //开全局中断

  68.     ADC_int( );

  69.    while(1);
  70. }
  71. //-----------------------------------------------------------------
  72. // AD转换中断读数据,TMR0定时器溢出中断控制数码管刷新显示两路A/D转换结果
  73. //-----------------------------------------------------------------
  74. void interrupt AD_TMR0_ISR( )
  75. {  
  76.    static INT8U Display_Buffer[8] = {0,0,0,10,0,0,0,10};
  77.    static INT8U  k = 0 ;
  78.    //*************
  79.    static unsigned int  Result = 0;
  80.    if(ADIF&&(k==7)) //强制16ms获取一次AD转换中断结果,否则显示闪烁
  81.      {               //也就是timer0中断8次,AD转换中断才发生一次
  82.                      //从而提高显示的刷新率  
  83.         //读取转换结果,并转换为电压值
  84.         //参考电压5v,所以转换结果*500/1023.0,使结果在000~500间
  85.         unsigned int Result = (unsigned int)((ADRESL | (ADRESH << 8)) *500.0 / 1023.0);
  86.         Display_Buffer[0 +4*CHS0] = Result / 100;
  87.             Display_Buffer[1+4*CHS0] = Result / 10 % 10;
  88.             Display_Buffer[2+4*CHS0] = Result % 10;
  89.          /************
  90.          Display_Buffer[2+4*CHS0]=0;
  91.          while(Result > 100){Result -= 100;Display_Buffer[2+4*CHS0]++;}
  92.          while(Result > 10){Result -= 10;Display_Buffer[1+4*CHS0]++;}
  93.          Display_Buffer[0 +4*CHS0] = Result;
  94.          ****************/
  95.         //if(++j > 1)   j=0;
  96.         CHS0 ^= 1;
  97.         GODONE = 1;              //改变通道后要重新启动AD转换
  98.         ADIF = 0;
  99.      }   
  100.    if(T0IF && T0IE)
  101.      {
  102.         TMR0 = (INT8U)(256 - _XTAL_FREQ / 4 / 16 * 0.002);//位间延时间隔2ms
  103.         RST = 0;                         //两只74HC164复位,输出为0
  104.         RST = 1;                         //拉高复位脚,允许74HC164输出
  105.                 Serial_Output(0x01<<k);                             //先送扫描码
  106.                 Serial_Output(SEG_CODE[Display_Buffer[k]]); //后送段码
  107.             k =(k+1)&0x07;
  108.         T0IF = 0;                         //清TMR0中断标志
  109.      }           
  110. }                 

评论

换单片机  发表于 2025-3-23 18:12
Wxy8030 发表于 2025-3-22 22:20 来自手机 | 显示全部楼层
换个内存大的呗
 楼主| lvsezhidu 发表于 2025-3-23 09:20 | 显示全部楼层
关键是早期买的几块PIC12F675、PIC12F629一直没用,想利用一下,
资深技术 发表于 2025-3-23 11:41 | 显示全部楼层
依以前用这个芯片的感觉, 完成 “2路AD转换,采用2只74ls164驱动8只集成数码管显示2路AD转换结果” 这个需求,这个芯片的容量够了。看看程序能不能精简。
mbutterfly 发表于 2025-3-23 14:04 | 显示全部楼层
换大点的RAM的型号,要不就是精简程序,少用全局数组变量。
 楼主| lvsezhidu 发表于 2025-3-23 14:08 | 显示全部楼层
把AD转换放主函数里也是显示内存小,编译不通过,我用的是H_TECH software编辑器,不知在哪设置代码优化级别,请前辈告知。

 楼主| lvsezhidu 发表于 2025-3-23 14:15 | 显示全部楼层
本帖最后由 lvsezhidu 于 2025-3-23 14:17 编辑

C:\Users\Administrator\Desktop
 楼主| lvsezhidu 发表于 2025-3-23 14:18 | 显示全部楼层
编译结果如下:
Build D:\desktop\PIC12F675_gai\main for device 12F675
Using driver C:\Program Files (x86)\HI-TECH Software\PICC\9.80\bin\picc.exe

Make: The target "D:\desktop\PIC12F675_gai\main.p1" is out of date.
Executing: "C:\Program Files (x86)\HI-TECH Software\PICC\9.80\bin\picc.exe" --pass1 D:\desktop\PIC12F675_gai\main.c -q --chip=12F675 -P --runtime=default,+clear,+init,-keep,+osccal,-download,-resetbits,-stackcall,+clib --opt=default,+asm,-debug,-speed,+space,9 --warn=0 -D__DEBUG=1 --double=24 --float=24 --addrqual=ignore -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
Executing: "C:\Program Files (x86)\HI-TECH Software\PICC\9.80\bin\picc.exe" -omain.cof -mmain.map --summary=default,-psect,-class,+mem,-hex --output=default,-inhx032 main.p1 --chip=12F675 -P --runtime=default,+clear,+init,-keep,+osccal,-download,-resetbits,-stackcall,+clib --opt=default,+asm,-debug,-speed,+space,9 --warn=0 -D__DEBUG=1 --double=24 --float=24 --addrqual=ignore -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
HI-TECH C Compiler for PIC10/12/16 MCUs (PRO Mode)  V9.80
Copyright (C) 2010 Microchip Technology Inc.
Serial number: HCPICP-111111 (PRO)
Error   [1358] D:\desktop\PIC12F675_gai\main.c; 182. no space for ___ftdiv temps (3)

********** Build failed! **********
xch 发表于 2025-3-23 17:10 | 显示全部楼层
本帖最后由 xch 于 2025-3-23 17:13 编辑

代码框架没设计好。64字节内存足够了。

中断服务之中不需要做太多工作。做个标记清除中断即可。
在main 函数while 循环中根据标记做需要的操作。标记仅占用一个字节。但是中断中用到的寄存器系统以为都需要保护,会占用更多ram。


GlenX 发表于 2025-3-24 20:38 | 显示全部楼层
减少全局变量,尽量使用局部变量。
banyai 发表于 2025-3-25 19:52 | 显示全部楼层
这段语句要优化,不要用浮点运算,大数的乘除法,尽量用移位和加减法取代:
unsigned int Result = (unsigned int)((ADRESL | (ADRESH << 8)) *500.0 / 1023.0);
Display_Buffer[0 +4*CHS0] = Result / 100;
Display_Buffer[1+4*CHS0] = Result / 10 % 10;
Display_Buffer[2+4*CHS0] = Result % 10;

评论

正解 芯片连乘法器都没有, 使用浮点运算是不可取的 (ADRESL | (ADRESH << 8), 如果ADRESH 是 8bit的话, 这里溢出了。  发表于 2025-4-1 21:39
GlenX 发表于 2025-4-13 21:41 | 显示全部楼层
volatile INT8U k = 0, j = 0;
这个在使用前定义就可以,不需要全局!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

7

主题

24

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部