C51 COMPILER V9.59.0.0 MAIN 06/09/2021 13:32:31 PAGE 1 C51 COMPILER V9.59.0.0, COMPILATION OF MODULE MAIN OBJECT MODULE PLACED IN .\list\main.obj COMPILER INVOKED BY: C:\Keil_v5\C51\BIN\C51.EXE main.c OMF2 OPTIMIZE(8,SPEED) BROWSE DEBUG PRINT(.\list\main.lst) TABS(2 -) OBJECT(.\list\main.obj) line level source 1 /*---------------------------------------------------------------------*/ 2 /* --- STC MCU Limited ------------------------------------------------*/ 3 /* --- STC 1T Series MCU Demo Programme -------------------------------*/ 4 /* --- Mobile: (86)13922805190 ----------------------------------------*/ 5 /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/ 6 /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/ 7 /* --- Web: www.STCMCU.com --------------------------------------------*/ 8 /* --- Web: www.STCMCUDATA.com ---------------------------------------*/ 9 /* --- QQ: 800003751 -------------------------------------------------*/ 10 /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */ 11 /*---------------------------------------------------------------------*/ 12 13 #include "config.h" 14 #include "STC8A_GPIO.h" 15 #include "STC8A_UART.h" 16 #include "STC8A_NVIC.h" 17 #include "STC8A_Delay.h" 18 #include "STC8A_EEPROM.h" 19 20 /************* 本程序功能说明 ************** 21 22 通过串口对STC内部自带的EEPROM(FLASH)进行读写测试。 23 24 对FLASH做扇区擦除、写入、读出的操作,命令指定地址。 25 26 默认波特率: 115200,N,8,1. 27 28 串口命令设置: (命令字母不区分大小写) 29 E 0x0040 --> 对0x0040地址扇区内容进行擦除. 30 W 0x0040 1234567890 --> 对0x0040地址写入字符1234567890. 31 R 0x0040 10 --> 对0x0040地址读出10个字节数据. 32 33 注意:下载时,下载界面"硬件选项"中设置用户EEPROM大小, 34 35 并确保串口命令中的地址在EEPROM设置的大小范围之内。 36 37 下载时, 选择时钟 22.1184MHz (可以在配置文件"config.h"中修改). 38 39 ******************************************/ 40 41 #define Max_Length 100 //读写EEPROM缓冲长度 42 43 /************* 本地常量声明 **************/ 44 45 46 /************* 本地变量声明 **************/ 47 u8 xdata tmp[Max_Length]; //EEPROM操作缓冲 48 49 50 /************* 本地函数声明 **************/ 51 52 53 /************* 外部函数和变量声明 *****************/ 54 C51 COMPILER V9.59.0.0 MAIN 06/09/2021 13:32:31 PAGE 2 55 56 /******************* IO配置函数 *******************/ 57 void GPIO_config(void) 58 { 59 1 GPIO_InitTypeDef GPIO_InitStructure; //结构定义 60 1 61 1 GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7 62 1 GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_O -UT_PP 63 1 GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化 64 1 } 65 66 /*************** 串口初始化函数 *****************/ 67 void UART_config(void) 68 { 69 1 COMx_InitDefine COMx_InitStructure; //结构定义 70 1 71 1 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART -_9bit_BRTx 72 1 COMx_InitStructure.UART_BRT_Use = BRT_Timer1; //使用波特率, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使 -用BRT_Timer2) 73 1 COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200 74 1 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE 75 1 COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE 76 1 UART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4 77 1 NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Pri -ority_2,Priority_3 78 1 } 79 80 /**********************************************/ 81 82 u8 CheckData(u8 dat) 83 { 84 1 if((dat >= '0') && (dat <= '9')) return (dat-'0'); 85 1 if((dat >= 'A') && (dat <= 'F')) return (dat-'A'+10); 86 1 if((dat >= 'a') && (dat <= 'f')) return (dat-'a'+10); 87 1 return 0xff; 88 1 } 89 90 //======================================================================== 91 // 函数: u16 GetAddress(void) 92 // 描述: 计算各种输入方式的地址. 93 // 参数: 无. 94 // 返回: 16位EEPROM地址. 95 // 版本: V1.0, 2013-6-6 96 //======================================================================== 97 u16 GetAddress(void) 98 { 99 1 u16 address; 100 1 u8 i,j; 101 1 102 1 address = 0; 103 1 if((RX1_Buffer[2] == '0') && (RX1_Buffer[3] == 'X')) 104 1 { 105 2 for(i=4; i<8; i++) 106 2 { 107 3 j = CheckData(RX1_Buffer[i]); 108 3 if(j >= 0x10) return 65535; //error 109 3 address = (address << 4) + j; 110 3 } 111 2 return (address); 112 2 } C51 COMPILER V9.59.0.0 MAIN 06/09/2021 13:32:31 PAGE 3 113 1 return 65535; //error 114 1 } 115 116 /**************** 获取要读出数据的字节数 ****************************/ 117 u8 GetDataLength(void) 118 { 119 1 u8 i; 120 1 u8 length; 121 1 122 1 length = 0; 123 1 for(i=9; i= 10) break; 126 2 length = length * 10 + CheckData(RX1_Buffer[i]); 127 2 } 128 1 return (length); 129 1 } 130 131 /********************* 主函数 *************************/ 132 void main(void) 133 { 134 1 u8 i,j; 135 1 u16 addr; 136 1 u8 status; 137 1 138 1 GPIO_config(); 139 1 UART_config(); 140 1 EA = 1; 141 1 142 1 PrintString1("STC8系列单片机EEPROM测试程序,串口命令设置如下:\r\n"); //UART1发送一个字符串 143 1 PrintString1("E 0x0040 --> 对0x0040地址扇区内容进行擦除.\r\n"); //UART1发送一个字符串 144 1 PrintString1("W 0x0040 1234567890 --> 对0x0040地址写入字符1234567890.\r\n"); //UART1发送一个字符串 145 1 PrintString1("R 0x0040 10 --> 对0x0040地址读出10个字节内容.\r\n"); //UART1发送一个字符串 146 1 while(1) 147 1 { 148 2 delay_ms(1); 149 2 if(COM1.RX_TimeOut > 0) //超时计数 150 2 { 151 3 if(--COM1.RX_TimeOut == 0) 152 3 { 153 4 for(i=0; i= 8) && (RX1_Buffer[1] == ' ')) //最短命令为8个字节 157 4 { 158 5 for(i=0; i<8; i++) 159 5 { 160 6 if((RX1_Buffer[i] >= 'a') && (RX1_Buffer[i] <= 'z')) RX1_Buffer[i] = RX1_Buffer[i] - 'a' + 'A'; -//小写转大写 161 6 } 162 5 addr = GetAddress(); 163 5 if(addr < 63488) //限制在0~123扇区 164 5 { 165 6 if(RX1_Buffer[0] == 'E') //写入N个字节 166 6 { 167 7 EEPROM_SectorErase(addr); //擦除扇区 168 7 PrintString1("擦除成功!\r\n"); 169 7 status = 0; //命令正确 170 7 } 171 6 172 6 else if((RX1_Buffer[0] == 'W') && (RX1_Buffer[8] == ' ')) //写入N个字节 173 6 { C51 COMPILER V9.59.0.0 MAIN 06/09/2021 13:32:31 PAGE 4 174 7 j = COM1.RX_Cnt - 9; 175 7 if(j > Max_Length) j = Max_Length; //越界检测 176 7 //EEPROM_SectorErase(addr); //擦除扇区 177 7 EEPROM_write_n(addr,&RX1_Buffer[9],j); //写N个字节 178 7 PrintString1("已写入"); 179 7 if(j >= 100) {TX1_write2buff(j/100+'0'); j = j % 100;} 180 7 if(j >= 10) {TX1_write2buff(j/10+'0'); j = j % 10;} 181 7 TX1_write2buff(j%10+'0'); 182 7 PrintString1("字节!\r\n"); 183 7 status = 0; //命令正确 184 7 } 185 6 186 6 else if((RX1_Buffer[0] == 'R') && (RX1_Buffer[8] == ' ')) //PC请求返回N字节EEPROM数据 187 6 { 188 7 j = GetDataLength(); 189 7 if(j > Max_Length) j = Max_Length; //越界检测 190 7 if(j > 0) 191 7 { 192 8 PrintString1("读出"); 193 8 TX1_write2buff(j/10+'0'); 194 8 TX1_write2buff(j%10+'0'); 195 8 PrintString1("个字节内容如下:\r\n"); 196 8 EEPROM_read_n(addr,tmp,j); 197 8 for(i=0; i