找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8|回复: 1
打印 上一主题 下一主题
收起左侧

有大神帮我改一下单片机代码吗? eeprom的按字节写入

[复制链接]
跳转到指定楼层
楼主
ID:1130333 发表于 2024-10-22 20:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
首先定义一个sbit cap=P32;
P32 连接一个22uf电容,然后接地.,上电后 P32在 0.5秒后,充满电应该是属于低电平,(P32=0)
在这0.5秒内,应该属于高电平(P32=1).
那我直接判断 if(P32==1) 那就写eeprom(按字节写入), 如果P32==0 那就读取上一次写的eeprom

这不就实现我的需求了吗?  按照这个逻辑,我自己写了一个代码 .但是老是有问题.

单片机源程序如下:
  1. #include "stc8g.h"
  2. #include "intrins.h"
  3. #include <stdio.h>

  4. #define MAIN_Fosc 11059200UL
  5. #define BRT         (65536 - MAIN_Fosc / 115200 / 4)

  6. typedef unsigned char u8;
  7. typedef unsigned int u16;

  8. u8 dat;                                                //定义eeprom 储存数据,但实际好像没用上
  9. u16 EEPROMId = 0x0020;                                //定义eeprom的地址

  10. sbit cap = P3^2;                                        //p32引脚连电容,接地 做电平判定

  11. void sys_init();                                        //声明系统初始化配置
  12. void PWM_init(void);                                //声明pwm

  13. void main()
  14. {               
  15.         unsigned char x;                                 //定义变量x 用于读取eeprom
  16.         unsigned char y=5;                        //定义变量y用于保存pwm值
  17.         sys_init();                                  //调用系统配置

  18.           P3M0 = 0x00; P3M1 = 0x00;                //P32 输出对电容充电
  19.           P5M0 = 0x00; P5M1 = 0x00;                   //pwm 设置在p55口

  20.         x = IapRead(EEPROMId);                        //读取的当前eeprom 赋值给x        
  21.         
  22.           while(1)
  23.         {         
  24.                 if(cap)                                //如果p32引脚 充电中 p32==1
  25.                 {
  26.                 IapProgram(EEPROMId,y);                //写地址为0x0020 为 y(以后设置为switch或者数组)

  27.                 EEPROMId=EEPROMId+1;                //下次写eeprom +1  0x0021 ,在下次0x0022 以此类推
  28.                 y=y+1;                                //pwm亮度 数组+1   (1,15,55,255)
  29.          
  30.                 }
  31.                  CCAP2H=x;                                //把x写入的值 赋值给pwm

  32.                 if(EEPROMId >= 0X1FE)                                //如果当前字节到达EEPROM末尾,擦除扇区数据
  33.                  {        
  34.                           IapErase(0x0020);                                //擦除扇区
  35.                  
  36.                         EEPROMId = 0x0020;                        //从头开始按字节写入
  37.                  }
  38.         }
  39. }

  40. void sys_init(void)
  41. {
  42.         P_SW2=0x80;
  43.       PWM_init();
  44.         EA=1;                        //打开总中断
  45. }


  46. //// 初始化PWM功能 P55 pwm
  47. void PWM_init(void)
  48. {
  49.     P_SW1=0x20;
  50.     CCON = 0x00;
  51.     CMOD = 0x08;
  52.     CL = 0x00;
  53.     CH = 0x00;

  54.     CCAPM2 = 0x42;
  55.     PCA_PWM2 = 0x00;
  56.     CCAP2L = 0x00;                  
  57.     CCAP2H = 0x00;
  58.     CR=1;        
  59. }

  60. void delayms(u16 ms)
  61. {
  62.         unsigned int i;
  63.         do{
  64.                 i = MAIN_Fosc /10000;
  65.                 while(--i);
  66.         }while(--ms);
  67. }

  68. void IapIdle()
  69. {
  70.         IAP_CONTR = 0;                                                 // 关闭 IAP 功能
  71.         IAP_CMD = 0;                                                         // 清除命令寄存器
  72.         IAP_TRIG = 0;                                                 // 清除触发寄存器

  73.         IAP_ADDRH = 0x00;                                        // 清零高地址寄存器
  74.         IAP_ADDRL = 0x00;                                        // 清零低地址寄存器
  75. }

  76. char IapRead(unsigned int addr)
  77. {
  78.         
  79.         char dat;
  80.         IAP_CONTR = 0x80;                                 // 使能 IAP
  81.         IAP_TPS = 12;                                                 // 设置等待参数 12MHz
  82.         IAP_CMD = 1;                                                         // 设置 IAP 读命令
  83.         IAP_ADDRL = addr;                                 // 设置 IAP 低地址
  84.         IAP_ADDRH = addr >> 8;                 // 设置 IAP 高地址
  85.         EA=0;
  86.         _nop_();
  87.         _nop_();        
  88.         IAP_TRIG = 0x5a;                                         // 写触发命令 (0x5a)
  89.         IAP_TRIG = 0xa5;                                         // 写触发命令 (0xa5)
  90.         EA=1;
  91.         _nop_();
  92.         _nop_();
  93.         _nop_();
  94.         _nop_();
  95.         dat = IAP_DATA;                                         // 读 IAP 数据
  96.         IapIdle();                                                                 // 关闭 IAP 功能
  97.         return dat;

  98. }
  99. void IapProgram(unsigned int addr, char dat)
  100. {

  101.         IAP_CONTR = 0x80;                                 // 使能 IAP
  102.         IAP_TPS = 12;                                                 // 设置等待参数 12MHz
  103.         IAP_CMD = 2;                                                        // 设置 IAP 写命令
  104.         IAP_ADDRL = addr;                                 // 设置 IAP 低地址
  105.         IAP_ADDRH = addr >> 8;                 // 设置 IAP 高地址

  106.         IAP_DATA = dat;                                         // 写 IAP 数据
  107.         EA=0;
  108.         _nop_();
  109.         _nop_();        
  110.         IAP_TRIG = 0x5a;                                         // 写触发命令 (0x5a)
  111.         IAP_TRIG = 0xa5;                                         // 写触发命令 (0xa5)
  112.         EA=1;        
  113.         _nop_();
  114.         _nop_();
  115.         _nop_();
  116.         _nop_();
  117.         IapIdle();                                                                // 关闭 IAP 功能

  118. }
  119. void IapErase(unsigned int addr)
  120. {

  121.         IAP_CONTR = 0x80;                                 // 使能 IAP
  122.         IAP_TPS = 12;                                                 // 设置等待参数 12MHz
  123.         IAP_CMD = 3;                                                         // 设置 IAP 擦除命令
  124.         IAP_ADDRL = addr;                                 // 设置 IAP 低地址
  125.         IAP_ADDRH = addr >> 8;                 // 设置 IAP 高地址

  126.         EA=0;
  127.         _nop_();
  128.         _nop_();        
  129.         IAP_TRIG = 0x5a;                                         // 写触发命令 (0x5a)
  130.         IAP_TRIG = 0xa5;                                         // 写触发命令 (0xa5)
  131.         EA=1;        
  132.         _nop_();
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         IapIdle();                                                                 // 关闭 IAP 功能

  137. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:57657 发表于 2024-10-22 22:34 | 只看该作者
字节读:可使用unsigned char/int/long code指针汇编成MOVC指令即可访问,不需要配置EEPROM寄存器,字节写将二进制1写为0且不可逆,必须扇区擦除才能恢复,没有字节擦除,擦除后全部为0xFF(二进制1),一次擦512字节。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表