找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC32G12K128屠龙刀+FT24C256A+MAX7219

[复制链接]
跳转到指定楼层
楼主
ID:1091140 发表于 2025-11-11 21:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近开始折腾STC32G12K128
买了块屠龙刀回来,手头有IIC的存储芯片FT24C256A

今天我们目的是使用STC的USB-CDC功能,在存储芯片上写入8个数值后读取出来,在数码管上显示,同时

要打印到PC机的串口(不用普通串口,用STC-USB-CDC串口)

先看器件:
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1091140 发表于 2025-11-11 21:47 | 只看该作者
先看主程序:
  1. //<<AICUBE_USER_HEADER_REMARK_BEGIN>>
  2. ////////////////////////////////////////
  3. // 在此添加用户文件头说明信息  
  4. // 文件名称: main.c
  5. // 文件描述:
  6. // 文件版本: V1.0
  7. // 修改记录:
  8. //   1. (2025-11-06) 创建文件
  9. ////////////////////////////////////////
  10. //<<AICUBE_USER_HEADER_REMARK_END>>


  11. #include "config.h"                     //默认已包含stdio.h、intrins.h等头文件


  12. //<<AICUBE_USER_INCLUDE_BEGIN>>
  13. // 在此添加用户头文件包含
  14. #include "i2c.h"
  15. #include "MAX7219.h"
  16. //        8位Max7219数码管模块显示, CLK = P6^4;CS = P6^5; DIN = P6^6;
  17. //选择I2C数据口: SCL(P2.5), SDA(P2.4),IIC分频系数n=60
  18. //<<AICUBE_USER_INCLUDE_END>>


  19. //<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
  20. // 在此添加用户全局变量定义、用户宏定义以及函数声明
  21. void PlaySMG(u8  tmp_1[8]);

  22. char code LEDcode[]=
  23. {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,0x00     /*0,1,2,3,4,5,6,7,8,9,全灭*/
  24. ,0x77,0x1f,0x4e,0x3d,0x4f,0x47,0x67,0x3e,0xff};    /*A,B,C,D,E,F,P,U,全亮*/


  25. char code table[]={
  26. 0x7e, //0
  27. 0x18, //1
  28. 0x37, //2
  29. 0x3d, //3
  30. 0x59, //4
  31. 0x6d, //5
  32. 0x6f, //6
  33. 0x38, //7
  34. 0x7f, //8
  35. 0x7d, //9
  36. 0x7b, //A
  37. 0x4F, //b
  38. 0x66, //C
  39. 0x1F, //d
  40. 0x67, //E
  41. 0x63,  //F
  42. };     //共阴
  43. //<<AICUBE_USER_GLOBAL_DEFINE_END>>



  44. ////////////////////////////////////////
  45. // 项目主函数
  46. // 入口参数: 无
  47. // 函数返回: 无
  48. ////////////////////////////////////////
  49. void main(void)
  50. {
  51.     //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
  52.     // 在此添加用户主函数初始化代码
  53.                 u8 i=0;
  54.                 u8  tmp[8];
  55.     //<<AICUBE_USER_MAIN_INITIAL_END>>

  56.     SYS_Init();

  57.     //<<AICUBE_USER_MAIN_CODE_BEGIN>>
  58.     // 在此添加主函数中运行一次的用户代码
  59.         Initial();               //MAX7219初始化
  60.                 P40 = 0;        //三极管引脚输出低电平
  61.                 P60 = 0;        //输出低电平   //这2颗灯亮了
  62.                 P61 = 0;        //输出低电平   //说明这段程序是执行了
  63.                 delay_ms(2000);//经STC论坛版主erci***指导“print_usb并非阻
  64.         //塞函数,所以在打开串口前可能已经打印完成了。 所以延时应放在打印前,或者在循环里
  65.         //每隔1s反复打印这样每次打开串口都能看到。”
  66. //                printf_usb( " A 首先从24C02读取8个数\xfd:            \r\n");  
  67. //                printf_usb( " B 把从24C02读取8个数\xfd加1后写入24C02:\r\n");
  68. //                printf_usb( " C 把从24C02读取8个数\xfd减1后写入24C02:\r\n");
  69. //                printf_usb( " D 把24C02地址0x0000的8个数\xfd清零:    \r\n");
  70.                 //printf_usb( " 发字符给printf_usb,引发bUsbInBusy检测    \r\n");
  71.                 //可以先printf再while(bUsbInBusy == 1);,但是这样依然看不到第一条printf的
  72.                 //while(bUsbInBusy==1) //cdc串口发数据之前可以判断一下当前的usb状态,等他空闲了再发,
  73.                                                          //实测这样一点问题没有,但是我们这里不行啊
  74.                 //{
  75.                 printf_usb( " A 首先从24C256读取8个数:            \r\n");  
  76.                 printf_usb( " B 把从24C256读取8个数加1后写入24C256:\r\n");
  77.                 printf_usb( " C 把从24C256读取8个数减1后写入24C256:\r\n");
  78.                 printf_usb( " D 把24C256地址0x0000k开始的8个数清零:    \r\n");
  79.                 //};
  80.                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  81.                
  82.                 for( i=0;i<8;i++ )
  83.                 {
  84.                 printf_usb( "%u\t ",tmp[i] );
  85.                 }                                                        //为什么串口助手看不到以上打印结果?
  86.                                                                         //可能是USB查询方式,只有在回答查询的时候才输出?
  87.                
  88.                
  89.                                                
  90.                 PlaySMG(tmp); //数码管打印8个字节
  91.        
  92.     //<<AICUBE_USER_MAIN_CODE_END>>

  93.     while (1)
  94.     {
  95.        // USBLIB_OUT_Done();              //查询方式处理USB接收的数据

  96.         //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
  97.         // 在此添加主函数中用户主循环代码
  98.                                         if( bUsbOutReady )                                                               
  99.                 {
  100.                         //USB_SendData(UsbOutBuffer,OutNumber);
  101.                
  102.                        
  103.                                
  104.                         switch( UsbOutBuffer[0] )
  105.                         {
  106.                                 case 'A':                        //
  107.                                             //printf("从24C02读出8个数\xfd据: \r\n");
  108.                                                 printf("从24C256读出8个数据: \r\n");

  109.                                                 //-----------------------读取数据-----------------------
  110.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  111.                                                
  112.                                                 for( i=0;i<8;i++ )
  113.                                                 {
  114.                                                 printf( "%u\t",tmp[i] );  
  115.                                                 /*  以十进制打印
  116.                                                 "%u\t" 是格式化字符串,其中:%u 是一个格式控制符,用于指定输出一个无符号整数。
  117.                                                 \t 是一个转义字符,表示输出一个水平制表符。dat[i] 是要输出的数据,它应该是一个无符号整数类型的数组元素。
  118.                                                 %u格式控制符用于将数字转换为无符号整数格式。无符号整数是指不带符号的整数,即只能表示零和正数的整数类型
  119.                                                 */

  120.                                                 }
  121.                                                 printf( "读取结束\r\n");
  122.                                                
  123.                                                 PlaySMG(tmp); //数码管打印8个字节
  124.                                                 delay_ms(200);
  125.                                        
  126.                                         break;
  127.                                 case 'B':
  128.                                                
  129.                                                 printf( " B 把从24C256读取8个数加1后写入24C02:\r\n");

  130.                                                 //-----------------------写入修改后的数据-----------------------
  131.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  132.                                                 for( i=0;i<8;i++ )
  133.                                                 {
  134.                                                         tmp[i] = (tmp[i] +1);
  135.                                                 }       
  136.                                                 IIC_Write_NByte(0x00,0x08,tmp,8); //从地址 0x0008 开始,读取8个字节,都加1后,原位置写回去
  137.                                                
  138.                                                 delay_ms(200);
  139.                                                 printf("加1后存储完成再从24C256读出8个数据: \r\n");
  140.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  141.                                                
  142.                                                 for( i=0;i<8;i++ )
  143.                                                 {
  144.                                                 printf( "%u\t",tmp[i] );
  145.                                                 }
  146.                                                
  147.                                                 PlaySMG(tmp); //数码管打印8个字节
  148.                                                 delay_ms(200);
  149.                                                
  150.                                                 printf("请比较差别,证实加1写入成功\r\n");
  151.                                                 break;
  152.                                 case 'C':
  153.                                                
  154.                                                 printf( " C 把从24C256读取8个数减1后写入24C256:\r\n");
  155.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  156.                                                 for( i=0;i<8;i++ )
  157.                                                 {
  158.                                                         tmp[i] = (tmp[i] -1);
  159.                                                 }       
  160.                                                 IIC_Write_NByte(0x00,0x08,tmp,8); //从地址 0x0008 开始,读取8个字节,都减1后,原位置写回去
  161.                                                
  162.                                                 delay_ms(200);
  163.                                                
  164.                                                 printf("减1后存储完成再从24C256读出8个数据: \r\n");
  165.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  166.                                                
  167.                                                 for( i=0;i<8;i++ )
  168.                                                 {
  169.                                                 printf( "%u\t",tmp[i] );
  170.                                                 }
  171.                                                 delay_ms(200);
  172.                                                
  173.                                                 printf("请再次比较差别,证实减1写入成功\r\n");
  174.                                                 PlaySMG(tmp); //数码管打印8个字节
  175.                                                 break;
  176.                                 case 'D':
  177.                                                 printf( " D 把24C256地址0x0000开始的8个数清零::\r\n");
  178.                                
  179.                                                 for( i=0;i<8;i++ )
  180.                                                 {
  181.                                                         tmp[i] = 0x00;
  182.                                                 }       
  183.                                                 IIC_Write_NByte(0x00,0x08,tmp,8); //从地址 0x0008 开始,数组成员都变0后,原位置写回去
  184.                                                
  185.                                                 delay_ms(200);
  186.                                                
  187.                                                 printf( " D 24C256地址0x0000开始的8个数已经变成::\r\n");
  188.                                                 IIC_Read_NGByte(0x00,0x08,tmp,8);        // 从地址 0x0008 开始,读取8个字节,存入tmp[8]中
  189.                                                
  190.                                                 for( i=0;i<8;i++ )
  191.                                                 {
  192.                                                 printf( "%u\t",tmp[i] );
  193.                                                 }
  194.                                                 delay_ms(200);
  195.                                                
  196.                                                 printf("请再次比较差别,证实清零成功\r\n");
  197.                                                 PlaySMG(tmp); //数码管打印8个字节
  198.                                                 break;
  199.                                
  200.                                 default:
  201.                                                                                                
  202.                                                 break;                               
  203.                         }
  204.                         usb_OUT_done();
  205.                
  206.                 }
  207.                
  208.         //<<AICUBE_USER_MAIN_LOOP_END>>
  209.     }
  210. }

  211. ////////////////////////////////////////
  212. // 系统初始化函数
  213. // 入口参数: 无
  214. // 函数返回: 无
  215. ////////////////////////////////////////
  216. void SYS_Init(void)
  217. {
  218.     EnableAccessXFR();                  //使能访问扩展XFR
  219.     AccessCodeFastest();                //设置最快速度访问程序代码
  220.     AccessIXramFastest();               //设置最快速度访问内部XDATA
  221.     IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基

  222.     //<<AICUBE_USER_PREINITIAL_CODE_BEGIN>>
  223.     // 在此添加用户预初始化代码  
  224.     //<<AICUBE_USER_PREINITIAL_CODE_END>>

  225.     P0M0 = 0x00; P0M1 = 0x00;           //初始化P0口为准双向口模式
  226.     P1M0 = 0x00; P1M1 = 0x00;           //初始化P1口为准双向口模式
  227.     P2M0 = 0x00; P2M1 = 0x00;           //初始化P2口为准双向口模式
  228.     P3M0 = 0x00; P3M1 = 0x00;           //初始化P3口为准双向口模式
  229.     P4M0 = 0x00; P4M1 = 0x00;           //初始化P4口为准双向口模式
  230.     P5M0 = 0x00; P5M1 = 0x00;           //初始化P5口为准双向口模式
  231.     P6M0 = 0x00; P6M1 = 0x00;           //初始化P6口为准双向口模式
  232.     P7M0 = 0x00; P7M1 = 0x00;           //初始化P7口为准双向口模式

  233.     I2C_Init();                         //I2C初始化
  234.     delay_ms(1);
  235.     USBLIB_Init();                      //USB库初始化
  236.     delay_ms(1);

  237.     //<<AICUBE_USER_INITIAL_CODE_BEGIN>>
  238.     // 在此添加用户初始化代码  
  239.     //<<AICUBE_USER_INITIAL_CODE_END>>

  240.     EnableGlobalInt();                  //使能全局中断
  241.     USBLIB_WaitConfiged();              //等待USB完成配置
  242. }

  243. ////////////////////////////////////////
  244. // 微秒延时函数
  245. // 入口参数: us (设置延时的微秒值)
  246. // 函数返回: 无
  247. ////////////////////////////////////////
  248. void delay_us(uint16_t us)
  249. {
  250.     do
  251.     {
  252.         NOP(18);                        //(MAIN_Fosc + 500000) / 1000000 - 6
  253.     } while (--us);
  254. }


  255. ////////////////////////////////////////
  256. // 毫秒延时函数
  257. // 入口参数: ms (设置延时的毫秒值)
  258. // 函数返回: 无
  259. ////////////////////////////////////////
  260. void delay_ms(uint16_t ms)
  261. {
  262.     uint16_t i;

  263.     do
  264.     {
  265.         i = MAIN_Fosc / 6000;
  266.         while (--i);
  267.     } while (--ms);
  268. }


  269. //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
  270. // 在此添加用户函数实现代码
  271. ////////////////////////////////////////
  272. // MAX7219显示函数
  273. // 入口参数: tmp_1[8]数组 (要显示的8个数的数组)
  274. // 函数返回: 无
  275. ////////////////////////////////////////
  276. void PlaySMG(u8  tmp_1[8])
  277. {

  278.                 Write7219(8,tmp_1[0]);                //数码管左边第1位,如果给15就是熄灭
  279.                 Write7219(7,tmp_1[1]);                //数码管左边第2位
  280.                 Write7219(6,tmp_1[2]);                //数码管左边第3位
  281.                 Write7219(5,tmp_1[3]);                 //数码管左边第4位
  282.                 Write7219(4,tmp_1[4]);                //数码管左边第5位,如果给15就是熄灭
  283.                 Write7219(3,tmp_1[5]);                //数码管左边第6位
  284.                 Write7219(2,tmp_1[6]);                //数码管左边第7位
  285.                 Write7219(1,tmp_1[7]);                 //数码管左边第8位 99--3 100--4 101--5 102--6 103--7  104--8 105--9
  286.                 //Write7219(1,LEDcode[14]|0x80);                 //数码管左边第8位  106--"-" 107--E  108--H 109--L 91--E 92--H


  287. }

  288. //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>


复制代码



回复

使用道具 举报

板凳
ID:1091140 发表于 2025-11-11 21:48 | 只看该作者
接着看IIC.C
  1. //<<AICUBE_USER_HEADER_REMARK_BEGIN>>
  2. ////////////////////////////////////////
  3. // 在此添加用户文件头说明信息  
  4. // 文件名称: i2c.c
  5. // 文件描述:
  6. // 文件版本: V1.0
  7. // 修改记录:
  8. //   1. (2025-11-06) 创建文件
  9. ////////////////////////////////////////
  10. //<<AICUBE_USER_HEADER_REMARK_END>>


  11. #include "config.h"


  12. //<<AICUBE_USER_INCLUDE_BEGIN>>
  13. // 在此添加用户头文件包含
  14. #include "i2c.h"
  15. //<<AICUBE_USER_INCLUDE_END>>


  16. //<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
  17. // 在此添加用户全局变量定义、用户宏定义以及函数声明
  18. bit zjyd_ASK;   //zjyd_ASK=0 就是ASK zjyd_ASK=1 就是NASK
  19. u8 dat;
  20. //<<AICUBE_USER_GLOBAL_DEFINE_END>>



  21. ////////////////////////////////////////
  22. // I2C初始化函数
  23. // 入口参数: 无
  24. // 函数返回: 无
  25. ////////////////////////////////////////
  26. void I2C_Init(void)
  27. {
  28.     I2C_SwitchP2425();                  //选择I2C数据口: SCL(P2.5), SDA(P2.4)

  29.     I2C_MasterMode();                   //设置I2C为主机模式
  30.     I2C_SetClockDivider(60);            //设置I2C为主机模式时钟

  31.     I2C_Enable();                       //使能I2C功能

  32.     //<<AICUBE_USER_I2C_INITIAL_BEGIN>>
  33.     // 在此添加用户初始化代码  
  34.     //<<AICUBE_USER_I2C_INITIAL_END>>
  35. }

  36. ////////////////////////////////////////
  37. // 主机模式等待命令完成
  38. // 入口参数: 无
  39. // 函数返回: 无
  40. ////////////////////////////////////////
  41. void I2C_MasterWait(void)
  42. {
  43.     while (!I2C_CheckMasterFlag());     //等待完成标志
  44.     I2C_ClearMasterFlag();              //清除完成标志
  45.     I2C_Idle();                         //恢复IDLE状态
  46. }

  47. ////////////////////////////////////////
  48. // 主机模式发送起始信号
  49. // 入口参数: 无
  50. // 函数返回: 无
  51. ////////////////////////////////////////
  52. void I2C_MasterStart(void)
  53. {
  54.     I2C_Start();                        //触发主机模式起始命令
  55.     I2C_MasterWait();                   //等待命令完成
  56. }

  57. ////////////////////////////////////////
  58. // 主机模式发送停止信号
  59. // 入口参数: 无
  60. // 函数返回: 无
  61. ////////////////////////////////////////
  62. void I2C_MasterStop(void)
  63. {
  64.     I2C_Stop();                         //触发主机模式停止命令
  65.     I2C_MasterWait();                   //等待命令完成
  66. }

  67. ////////////////////////////////////////
  68. // 主机模式发送1字节数据
  69. // 入口参数: dat (待发送的字节数据)
  70. // 函数返回: 0   (接收的应答信号为ACK)
  71. //           1   (接收的应答信号为NAK)
  72. ////////////////////////////////////////
  73. BOOL I2C_MasterSendByte(uint8_t dat)
  74. {
  75.     I2C_WriteData(dat);                 //将数据写入I2C数据寄存器
  76.     I2C_SendData();                     //触发主机模式写数据命令
  77.     I2C_MasterWait();                   //等待命令完成
  78.     I2C_RecvACK();                      //触发主机模式接收应答命令
  79.     I2C_MasterWait();                   //等待命令完成

  80.     return I2C_MasterReadACK();         //读取并返回应答信号
  81. }

  82. ////////////////////////////////////////
  83. // 主机模式接收1字节数据
  84. // 入口参数: ack (待发送的应答信号)
  85. // 函数返回:     (接收的字节数据)
  86. ////////////////////////////////////////
  87. uint8_t I2C_MasterReadByte(BOOL ack)
  88. {
  89.     uint8_t dat;

  90.     I2C_RecvData();                     //触发主机模式读数据命令
  91.     I2C_MasterWait();                   //等待命令完成
  92.     dat = I2C_ReadData();               //读取接收的数据
  93.     if (!ack)
  94.         I2C_MasterSetACK();             //将ACK数据写入寄存器
  95.     else
  96.         I2C_MasterSetNAK();             //将NAK数据写入寄存器
  97.     I2C_SendACK();                      //触发主机模式发送应答命令
  98.     I2C_MasterWait();                   //等待命令完成

  99.     return dat;                         //返回接收的数据
  100. }



  101. //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
  102. // 在此添加用户函数实现代码


  103. //存储地址超过2K的,要用16位地址
  104. ////////////////////////////////////////
  105. // 主机模式向IIC_24c256写入1字节数据
  106. // 入口参数: addrH(地址高8位),addrL(地址低8位),dat (待发送的1字节数据)
  107. // 函数返回:无
  108. //         
  109. ////////////////////////////////////////
  110. void IIC_Write1Gbyte(u8 addrH,u8 addrL, u8 dat)   //写入一个字节
  111. {
  112.         I2C_MasterStart();                         // START
  113.         zjyd_ASK = I2C_MasterSendByte(SLAW);       //发送从设备地址+写
  114.        
  115.         if(!zjyd_ASK)                              // 收到ASK就发送AT24C256地址高8位
  116.         {
  117.                 zjyd_ASK = I2C_MasterSendByte(addrH);  //写存储地址高8位

  118.                 if(!zjyd_ASK)                           // 收到ASK就发送AT24C256地址低8位
  119.                 {
  120.                 zjyd_ASK = I2C_MasterSendByte(addrL);   //写存储地址低8位       
  121.                         if(!zjyd_ASK)                              // 收到ASK就向AT24C256写1字节数据
  122.                         {
  123.                         zjyd_ASK = I2C_MasterSendByte(dat);   //写1字节数据       
  124.                         }
  125.                         if(zjyd_ASK)                        //应答是NASK,就中止
  126.                         return;
  127.                         I2C_MasterStop();                                 //发送停止命令
  128.                 }
  129.         }
  130.        
  131. }

  132. ////////////////////////////////////////
  133. // 主机模式读取1字节数据
  134. // 入口参数: addrH(地址高8位),addrL(地址低8位),ack (待发送的应答信号)
  135. // 函数返回:     (接收的字节数据)
  136. ////////////////////////////////////////
  137. void I2C_MasterRead1GByte(u8 addrH,u8 addrL)
  138. {

  139.        
  140.         I2C_MasterStart();                         // START
  141.         zjyd_ASK = I2C_MasterSendByte(SLAW);       //发送从设备地址+写
  142.        
  143.         if(!zjyd_ASK)                              // 收到ASK就发送AT24C256地址高8位
  144.         {
  145.                 zjyd_ASK = I2C_MasterSendByte(addrH);  //写存储地址高8位

  146.                 if(!zjyd_ASK)                           // 收到ASK就发送AT24C256地址低8位
  147.                 {
  148.                 zjyd_ASK = I2C_MasterSendByte(addrL);   //写存储地址低8位       
  149.                                 if(zjyd_ASK)                        //应答是NASK,就中止
  150.                                 return ;
  151.                                 else
  152.                                 {
  153.                                         I2C_MasterStart();                         // START
  154.                                         zjyd_ASK = I2C_MasterSendByte(SLAW);       //发送从设备地址+读
  155.                                                 if(!zjyd_ASK)                          // 收到ASK就向AT24C256读1字节数据
  156.                                                 {
  157.                                                 dat = I2C_MasterReadByte(zjyd_ASK);   //就读1个字节,入口参数是非应答
  158.                                                 I2C_MasterStop();                                 //发送停止命令
  159.                                                 }
  160.                                                
  161.                                 }
  162.                
  163.                 }
  164.         }
  165.        


  166. }


  167. //--------------------------------功能函数--------------------------------
  168. // (器件24C256的应答ASK或者NASK)
  169. //存储地址超过2K的,要用16位地址,连续读取iic几个字节的函数
  170. void IIC_Write_NByte(u8 addrH,u8 addrL, u8 *p, u8 number) /*  WordAddress,1st Data Address,2nd Data
  171. Address,Byte lenth 在芯片addrH+addrL开始的地址里写入p的内容,长度是number个字节,F0=0,right, F0=1,error */

  172. {                                               //
  173.         // 1. 发送起始信号+设备地址(写模式)
  174.         I2C_MasterStart();                          // START
  175.         zjyd_ASK = I2C_MasterSendByte(SLAW);       //主机模式发送1字节数据,函数返回: 接收的应答信号0为ACK),1为NAK
  176.                                                                                        // 设备地址 + 写命令(最后一位是0)
  177.         if(!zjyd_ASK)                              // 2. 收到ASK就发送AT24C02地址
  178.         {
  179.                 zjyd_ASK = I2C_MasterSendByte(addrH);  //写存储器地址高8位
  180.                 if(!zjyd_ASK)                           // 收到ASK就发送AT24C256地址低8位
  181.                 {
  182.                 zjyd_ASK = I2C_MasterSendByte(addrL);   //写存储地址低8位       
  183.                                 if(zjyd_ASK)                        //应答是NASK,就中止
  184.                                 return;
  185.                                 else
  186.                                 {
  187.                                         do                                                   //开始连续写number个字节
  188.                                         {
  189.                                                 zjyd_ASK = I2C_MasterSendByte(*p);    //写入数组p的内容去IIC
  190.                                                 p++;                                   //指针+1,主机模式写1字节数据,函数返回0为ACK, 1为NAK

  191.                                                 if(zjyd_ASK)  break;                   //出错了就终止
  192.                                                
  193.                                         }
  194.                                         while(--number);
  195.                                         I2C_MasterStop();                 //发送停止命令,结束IIC通信
  196.                                 }
  197.             }
  198.         }
  199.        
  200.    
  201.        
  202. }


  203. //连续读取iic几个字节的函数
  204. void IIC_Read_NGByte(u8 addrH, u8 addrL, u8 *p, u8 number)  //WordAddress,1st Data Address,2nd Data Address,Byte lenth   

  205. {
  206.         // 1. 发送起始信号+设备地址(写模式)
  207.         I2C_MasterStart();                   // START
  208.         zjyd_ASK = I2C_MasterSendByte(SLAW); //主机模式发送1字节,函数返回: 0(应答信号为ACK), 1(接收的应答信号为NAK)
  209.                                                                                  // 设备地址 + 写命令(最后一位是0)
  210.        
  211.         if(!zjyd_ASK)  // 2. 收到ASK就发送AT24C256高位地址
  212.                 zjyd_ASK = I2C_MasterSendByte(addrH);  //发送存储芯片AT24C256高位地址
  213.                        
  214.         if(!zjyd_ASK) // 3. 还能收到ASK就发送低位地址
  215.        
  216.                 zjyd_ASK = I2C_MasterSendByte(addrL);  //发送存储芯片AT24C256低位地址
  217.        
  218.         if(!zjyd_ASK) // 3. 还能收到ASK就发送起始信号
  219.         {
  220.         I2C_MasterStart();                     // START
  221.         zjyd_ASK = I2C_MasterSendByte(SLAR);   //发送设备地址+读命令
  222.         }
  223.         if(!zjyd_ASK) //4. 还能收到ASK连续读取number字节(最后1字节发送NACK)
  224.         {
  225.                         do
  226.                         {
  227.                          *p = I2C_MasterReadByte(zjyd_ASK); //主机模式接收1字节数据,入口参数: ack (待发送的应答信号)函数返回: (接收的字节数据)
  228.                                                                                                 //读取1字节数据函数
  229.                          p++;                                                                //指针+1
  230.                                        
  231.                         if(number!= 1)
  232.                                                
  233.                         zjyd_ASK=0;                     //发送ASK函数
  234.                         else
  235.                         zjyd_ASK=1;                     //发送NASK函数
  236.                                                        
  237.                         }while(--number);
  238.                                                  
  239.                         I2C_MasterStop();
  240.                                        
  241.         }       
  242.                                        
  243. }




  244. //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>


复制代码



回复

使用道具 举报

地板
ID:1091140 发表于 2025-11-11 21:50 | 只看该作者
接着是IIC.h
  1. //<<AICUBE_USER_HEADER_REMARK_BEGIN>>
  2. ////////////////////////////////////////
  3. // 在此添加用户文件头说明信息  
  4. // 文件名称: i2c.h
  5. ////////////////////////////////////////
  6. //<<AICUBE_USER_HEADER_REMARK_END>>


  7. #ifndef __I2C_H__
  8. #define __I2C_H__


  9. //<<AICUBE_USER_DEFINE_BEGIN>>
  10. // 在此添加用户宏定义
  11. #define SLAW    0xA0                                        // IIC地址+写 1010 0000          0xA0   (A2=0,A1=0,A0=0)
  12. #define SLAR    0xA1                                        // IIC地址+读 1010 0001             0xA1        (A2=0,A1=0,A0=0)
  13. //<<AICUBE_USER_DEFINE_END>>


  14. void I2C_Init(void);
  15. void I2C_MasterWait(void);
  16. void I2C_MasterStart(void);
  17. void I2C_MasterStop(void);
  18. BOOL I2C_MasterSendByte(uint8_t dat);
  19. uint8_t I2C_MasterReadByte(BOOL ack);



  20. //<<AICUBE_USER_EXTERNAL_DECLARE_BEGIN>>
  21. // 在此添加用户外部函数和外部变量声明
  22. extern  u8 dat;
  23. void IIC_Write1Gbyte(u8 addrH,u8 addrL, u8 dat);   //写入一个字节
  24. void I2C_MasterRead1GByte(u8 addrH,u8 addrL);
  25. void IIC_Write_NByte(u8 addrH,u8 addrL, u8 *p, u8 number); /*  WordAddress,1st Data Address,2nd Data
  26. Address,Byte lenth 在芯片addrH+addrL开始的地址里写入p的内容,长度是number个字节,F0=0,right, F0=1,error */
  27. void IIC_Read_NGByte(u8 addrH, u8 addrL, u8 *p, u8 number);  //WordAddress,1st Data Address,2nd Data Address,Byte lenth   

  28. //<<AICUBE_USER_EXTERNAL_DECLARE_END>>


  29. #endif
复制代码



回复

使用道具 举报

5#
ID:1091140 发表于 2025-11-11 21:51 | 只看该作者
再看MAX7219.c

  1. #include "MAX7219.h"
  2. #include "config.h"

  3. //地址、数据发送子程序
  4. void Write7219(unsigned char address,unsigned char dat)
  5. {  
  6.     unsigned char i;
  7.     CS=0;                       //拉低片选线,选中器件
  8.     //发送地址
  9.     for (i=0;i<8;i++)           //移位循环8次            
  10.     {   
  11.        CLK=0;                   //清零时钟总线
  12.        DIN=(bit)(address&0x80); //每次取高字节     
  13.        address<<=1;             //左移一位
  14.        CLK=1;                   //时钟上升沿,发送地址
  15.     }
  16.     //发送数据
  17.     for (i=0;i<8;i++)              
  18.     {  
  19.        CLK=0;
  20.        DIN=(bit)(dat&0x80);   
  21.        dat<<=1;
  22.        CLK=1;                  //时钟上升沿,发送数据
  23.     }
  24.     CS=1;                      //发送结束,上升沿锁存数据                     
  25. }
  26. //MAX7219初始化,设置MAX7219内部的控制寄存器
  27. void Initial(void)               
  28. {
  29.     Write7219(SHUT_DOWN,0x01);         //开启正常工作模式(0xX1)
  30.     Write7219(DISPLAY_TEST,0x00);      //选择工作模式(0xX0)
  31.     Write7219(DECODE_MODE,0xff);       //选用全译码模式
  32.     Write7219(SCAN_LIMIT,0x07);        //8只LED全用
  33.     Write7219(INTENSITY,0x02);         //设置初始亮度,共有16级可选择,用于设置SMG的显示亮度,从0x00~0x0F
  34. }
复制代码



回复

使用道具 举报

6#
ID:1091140 发表于 2025-11-11 21:52 | 只看该作者
接着是MAX7219.h
  1. #ifndef __MAX7219_H__
  2. #define __MAX7219_H__

  3. #include <STC32G.h>

  4. sbit CLK = P6^4;                   //MAX7219串行时钟CLK   
  5. sbit CS = P6^5;                          //MAX7219片选CS                 
  6. sbit DIN = P6^6;                   //MAX7219串行数据DIN     


  7. #define DECODE_MODE  0x09   //译码控制寄存器
  8. #define INTENSITY    0x0A   //亮度控制寄存器,有16级可选择,用于设置LED的显示亮度,从0xX0~0xXF
  9. #define SCAN_LIMIT   0x0B   //扫描界限寄存器
  10. #define SHUT_DOWN    0x0C   //关断模式寄存器
  11. #define DISPLAY_TEST 0x0F   //测试控制寄存器     

  12. void Write7219(unsigned char address,unsigned char dat);
  13. void Initial(void);

  14. #endif
复制代码



回复

使用道具 举报

7#
ID:1091140 发表于 2025-11-11 21:56 | 只看该作者
器件很简单:

STC32G12K128 屠龙刀1块,MAX7219  8位数码管1个 AT24C256 IIC 存储芯片一块

编译环境 :256

μVision V5.14.2

CKeil_v5\C251BIN C251.exe V5.60.0.0
A251.exe V4.69.13.0
L251.exe V4.66.93.0LIB251.exe OH251.exe S251.DLL DCORE51.DLL V4.30.1.0V1.47.0.0
V3.129.0.0
V2.81.6.0

回复

使用道具 举报

8#
ID:1091140 发表于 2025-11-11 22:00 | 只看该作者
最后我把程序打包,压缩发上来:


STC32G IIC256 MAX7219.zip

426.48 KB, 下载次数: 0, 下载积分: 黑币 -5

回复

使用道具 举报

9#
ID:1091140 发表于 2025-11-11 22:01 | 只看该作者
欢迎大家多交流
回复

使用道具 举报

10#
ID:1064915 发表于 2025-11-13 08:27 | 只看该作者
c251如何安装?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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