抽点心思 继续这个系列写下去哦 认真的总结呢
这程序针对的是M16的内部EEPROM 它的大小只有512个字节 对它的操作 是要注意它的操作时序 首先是先等待对EEPROM的操作(读或写)禁止 即是控制寄存器中的EEWE/EERE为0 然后写入地址 接着就写入数据到数据寄存器EEDR或读出数据 下面的实现的功能是这样的 PC通过串口发送字符串给EEPROM 发送@R 读EEPROM中的内容 并通过串口发送给PC
代码如下:
#include <iom16v.h >
#include <macros.h >
#define uchar unsigned char
uchar RecvFlag = 0; //串口接收到的数据
uchar Flag = 0; //为1时表示接收到了@,如果紧接着收到R则发送EEPROM中的数据
uint EEpromAdd = 0; //存储在EEPROM中的地址
uchar temp[255],tempcnt = 0; //暂存数据
uchar temp1; //暂存串口接收到的数据
uchar Flag = 0; //为1时表示接收到了@,如果紧接着收到R则发送EEPROM中的数据
uint EEpromAdd = 0; //存储在EEPROM中的地址
uchar temp[255],tempcnt = 0; //暂存数据
uchar temp1; //暂存串口接收到的数据
//EEPROM的写程序
void EepromWrite ( uint addr, uchar val) //向EEPROM写操作
{
while ( EECR&0x02 ); //判断EEWE是否为0
EEAR = addr;
EEDR = val;
CLI();
EECR = EECR|0x04; //置EEMWE为1
EECR = EECR|0x02; //置EEWE为1
SEI();
}
{
while ( EECR&0x02 ); //判断EEWE是否为0
EEAR = addr;
EEDR = val;
CLI();
EECR = EECR|0x04; //置EEMWE为1
EECR = EECR|0x02; //置EEWE为1
SEI();
}
//EEPROM读程序
void EepromRead (uchar num, uint addr, uchar *val) //向EEPROM读操作
{
while (num)
{
while ( EECR&0x01 ); //判断EEWE是否为0
EEAR = addr;
EECR = EECR|0x01; //置EERE为1
*val = EEDR;
addr++;
val++;
num--;
}
}
{
while (num)
{
while ( EECR&0x01 ); //判断EEWE是否为0
EEAR = addr;
EECR = EECR|0x01; //置EERE为1
*val = EEDR;
addr++;
val++;
num--;
}
}
//串口初始化
void Uart0Init(void) // AVR中串口的初始化程序
{
UCSRB = 0x00; //关串口
UCSRA = 0x02; //倍速模式 M16中文P151
UCSRC = BIT(URSEL) | 0x06; //写UCSRC寄存器,设定8个bit
UBRR = 206; //设定串口波特率为600
UCSRB = 0x98; //开串口
}
{
UCSRB = 0x00; //关串口
UCSRA = 0x02; //倍速模式 M16中文P151
UCSRC = BIT(URSEL) | 0x06; //写UCSRC寄存器,设定8个bit
UBRR = 206; //设定串口波特率为600
UCSRB = 0x98; //开串口
}
//串口中断服务函数
#pragma interrupt_handler UartRecvData:12
void UartRecvData(void)
{
temp1 = UDR;
RecvFlag = 1;
}
void UartRecvData(void)
{
temp1 = UDR;
RecvFlag = 1;
}
//发送字符串
void UartTransmitData(uchar *SendData, uint len)
{
uint i;
for( i = 0; i < len; i++)
{
while(!(UCSRA&0x20)); //判断数据寄存器是否为空
UDR = SendData[i];
}
}
{
uint i;
for( i = 0; i < len; i++)
{
while(!(UCSRA&0x20)); //判断数据寄存器是否为空
UDR = SendData[i];
}
}
//初始化各种信息
void InitDevices(void)
{
CLI(); //关全部中断
Uart0Init();
SEI(); //开全中断
}
{
CLI(); //关全部中断
Uart0Init();
SEI(); //开全中断
}
//主函数
void main ( void )
{
uchar EepromData[255] ;
uint j;
InitDevices();
while(j++);
EepromRead (255, 0, EepromData); //读取上次断电前程序存储的数据
UartTransmitData(EepromData, 255); //通过串口显示
while(1)11
{
if ( Flag == 2 )
{
Flag = 0;
EepromRead (EEpromAdd, 0, EepromData);//读取本次存储的数据,串口输出
UartTransmitData(EepromData, EEpromAdd);
}
if ( RecvFlag )
{
RecvFlag = 0;
if( temp1 == '@')
Flag = 1;
else if(((temp1 == 'R')||(temp1 == 'r'))&&( Flag == 1))//连续接收到@R
{
Flag = 2;
}
else
{
Flag = 0;
EepromWrite ( EEpromAdd++, temp1);
if ( EEpromAdd >= 255)
EEpromAdd = 0;
}
}
}
uint j;
InitDevices();
while(j++);
EepromRead (255, 0, EepromData); //读取上次断电前程序存储的数据
UartTransmitData(EepromData, 255); //通过串口显示
while(1)11
{
if ( Flag == 2 )
{
Flag = 0;
EepromRead (EEpromAdd, 0, EepromData);//读取本次存储的数据,串口输出
UartTransmitData(EepromData, EEpromAdd);
}
if ( RecvFlag )
{
RecvFlag = 0;
if( temp1 == '@')
Flag = 1;
else if(((temp1 == 'R')||(temp1 == 'r'))&&( Flag == 1))//连续接收到@R
{
Flag = 2;
}
else
{
Flag = 0;
EepromWrite ( EEpromAdd++, temp1);
if ( EEpromAdd >= 255)
EEpromAdd = 0;
}
}
}
}
转载于:https://blog.51cto.com/lengyiyun/197423