📄 iar-
字号:
/****************************************Copyright (c)****************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http:// www.embedtools.com
**
**--------------File Info---------------------------------------------------------------------------------
** File Name: ex55.c
** Last modified Date: 2007.9.24
** Last Version: V1.0
** Description: 对EEPROM进行编程
** 上位机通过串口将命令和数据发给下位机;下位机通过模拟I2C方式操作EEPROM。
**
**--------------------------------------------------------------------------------------------------------
** Created By: Kang qinhua
** Created date: 2007.9.24
** Version: V1.1
** Descriptions: The original version
**
**--------------------------------------------------------------------------------------------------------
** Modified by: Kang qinhua
** Modified date: 2008.01.13
** Version: v1.2
** Description:
**
*********************************************************************************************************/
#include "config.h"
#define CSI24c02 0xA0 /* EEPROM从机地址 */
#define EEPROMSize 256 /* EEPROM总字节数,24c02为256
字节 */
#define TMtimeout 600000 /* 接收超时时间0.1s */
#define TRA_BUF_LEN 300 /* 定义缓冲区长度 */
#define SDA GPIO_PIN_3 /* 模拟I2C数据传送位 */
#define SCL GPIO_PIN_2 /* 模拟I2C时钟控制位 */
uint8 TraBuf[TRA_BUF_LEN]; /* 创建缓冲区 */
uint8 StateY[7] = {'S', 'T', 'A', 'T', 'E', ':', 'Y'}; /* 回发状态Y */
uint8 StateN[7] = {'S', 'T', 'A', 'T', 'E', ':', 'N'}; /* 回发状态N */
uint8 UartTmr = 0; /* 串口计时器 */
/*********************************************************************************************************
** Function name: Timer1Init
** Descriptions: 初始化定时器1
** input parameters: Tick: 定时器装载值,也就是定时周期
** Prio: 中断优先级
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void Timer1Init(uint32 Tick, uint8 Prio)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); /* 使能定时器1系统外设 */
TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER); /* 设置定时器1为32位 */
TimerLoadSet(TIMER1_BASE, TIMER_A, Tick); /* 设置定时周期 */
IntEnable(INT_TIMER1A); /* 使能定时器1系统中断 */
TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); /* 使能超时中断 */
IntPrioritySet(INT_TIMER1A, Prio); /* 设置中断优先级 */
TimerEnable(TIMER1_BASE, TIMER_A); /* 打开定时器1 */
}
/*********************************************************************************************************
** Function name: Timer1A_ISR
** Descriptions: 定时器1中断处理函数
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void Timer1A_ISR(void)
{
UartTmr++; /* 串口计时器加1 */
TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); /* 清除中断标志 */
}
/*********************************************************************************************************
** Function name: ASCII_TO_HEX
** Descriptions: 将ASCII码转换为16进制数
** input parameters: data: 要转换的ASCII码
** output parameters: 无
** Returned value: 返回转换结果,低4位有效
*********************************************************************************************************/
uint8 ASCII_TO_HEX(uint8 data)
{
if(data > '9') {
data = data - 'A' + 0x0A; /* 转换'A'到'F' */
}
else {
data = data - '0'; /* 转换'0'到'9' */
}
data &= 0x0F;
return data;
}
/*********************************************************************************************************
** Function name: main
** Descriptions: 主函数
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
int main(void)
{
uint32 i = 0;
uint32 Position = 0; /* 当前接收数据的位置 */
uint8 Step = 0; /* 当前所处在的步骤 */
uint8 RecFin = 0; /* 接收完成标志 */
uint8 CommandCode; /* 命令代码 */
uint32 Address; /* 数据地址 */
uint32 DataLength; /* 数据长度 */
uint8 Result; /* 操作结果 */
delay(6000); /* 复位消抖10ms */
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ); /* 配置系统时钟,使用6MHz晶振 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); /* 配置模拟I2C所使用的引脚 */
GPIODirModeSet(GPIO_PORTB_BASE, SDA, GPIO_DIR_MODE_OUT);
GPIODirModeSet(GPIO_PORTB_BASE, SCL, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(GPIO_PORTB_BASE, SDA | SCL, /* 配置I2C的端口模式 */
GPIO_STRENGTH_2MA,
GPIO_PIN_TYPE_STD);
IntMasterEnable(); /* 使能全局中断 */
Uart0Init(115200, 1 << 5); /* 初始化串口0,波特率115200,
中断优先级为1 */
Timer1Init(TMtimeout, 3 << 5); /* 初始化定时器1,中断优先级为3*/
while(1) {
if ( QueueNData(Uart0_Rec_Queue) != 0 ) { /* 有接收到数据时进入 */
switch(Step) {
case 0: /* 第0步,判断接收到的字节是
否为'Z' */
QueueRead(TraBuf, Uart0_Rec_Queue);
if (TraBuf[0] == 'Z') {
Step++;
Position = 1;
}
break;
case 1: /* 第1步,再接收3个字节,判断接
收到的字节是否为'ZLG:' */
if ((Position >= 1) && (Position <= 3)) {
QueueRead(TraBuf + Position, Uart0_Rec_Queue);
Position++;
}
if (Position == 4) {
if ((TraBuf[1] == 'L') && (TraBuf[2] == 'G') && (TraBuf[3] == ':'))
{ Step++; }
else Step = 0; /* 如果不是'ZLG:'则返回第0步 */
}
break;
case 2: /* 第2步,再接收12个字节,收完
后处理 */
if ((Position >= 4) && (Position <= 15)) {
QueueRead(TraBuf + Position, Uart0_Rec_Queue);
Position++;
}
if (Position == 16) {
CommandCode = (ASCII_TO_HEX(TraBuf[4]) << 4) | ASCII_TO_HEX(TraBuf[5]);
Address = (ASCII_TO_HEX(TraBuf[6]) << 28) | (ASCII_TO_HEX(TraBuf[7]) << 24) |
(ASCII_TO_HEX(TraBuf[8]) << 20) | (ASCII_TO_HEX(TraBuf[9]) << 16) |
(ASCII_TO_HEX(TraBuf[10]) << 12)| (ASCII_TO_HEX(TraBuf[11]) << 8) |
(ASCII_TO_HEX(TraBuf[12]) << 4) | ASCII_TO_HEX(TraBuf[13]);
DataLength = (ASCII_TO_HEX(TraBuf[14]) << 4) | ASCII_TO_HEX(TraBuf[15]);
/* DataLength等于0代表数据长度
为整个EEPROM大小 */
if ( DataLength == 0 ) {
DataLength = EEPROMSize;
} /* 如果最后一个数据的地址超过
了EEPROM的范围则返回错误 */
if ((Address + DataLength) > EEPROMSize) {
CommandCode = 0xFF;
}
/* 如果指令为接收数据则下一步
接收,否则接收完成 */
if (CommandCode == 0x30) {
Step++;
}
else {
RecFin = 1;
}
}
break;
case 3: /* 第3步,按数据长度接收数据 */
if ((Position >= 16) && (Position <= DataLength + 15)) {
QueueRead(TraBuf + Position, Uart0_Rec_Queue);
Position++;
}
if ( Position == DataLength + 16 ) {
RecFin = 1; /* 接收完成 */
}
break;
default: /* 默认返回第0步 */
Step = 0;
break;
}
/* 重置定时器 */
TimerLoadSet(TIMER1_BASE, TIMER_A, TMtimeout);
UartTmr = 0;
}
if (RecFin) { /* 接收完成时进入 */
Result = 1; /* 初始化操作结果 */
switch (CommandCode) {
case 0x30: /* 将接收到的数据写入EEPROM */
for(i = 0; i < DataLength; i++) {
Result &= ISendStr(CSI24c02, Address + i, TraBuf + i + 16, 1);
delay(8000); /* 延时5-10ms */
}
if (Result) { /* 回发操作结果状态 */
Uart0Send(StateY, 7);
}
else {
Uart0Send(StateN, 7);
}
break;
case 0x20: /* 从EEPROM中读出数据并发给上
位机 */
for(i = 0; i < DataLength; i++) {
Result &= IRcvStr(CSI24c02, Address + i, TraBuf + i + 16, 1);
}
if (Result) { /* 判断读出是否正确 */
Uart0Send(TraBuf + 16, DataLength);
Uart0Send(StateY, 7);
}
else { /* 读出错误时,只回发操作结果
错误 */
Uart0Send(StateN, 7);
}
break;
default: /* 为其他命令代码时,回发操作
结果错误 */
Uart0Send(StateN, 7);
break;
}
Step = 0; /* 完成一帧操作后,清除状态寄
存器 */
RecFin = 0;
}
if ((QueueNData(Uart0_Rec_Queue) == 0) && (UartTmr > 0) && (Step > 0)) {
/* 如果接收到不完整的帧且超时,
则回发操作结果错误 */
Uart0Send(StateN, 7);
UartTmr = 0;
Step = 0;
}
}
/* return(0); */
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -