#include <Nordic\reg24le1.h>
#include <stdint.h>
#include <absacc.h>
//定义按键
sbit S3 = P0^7;
// 1/0=未按/按下
sbit S2 = P0^6;
// 1/0=未按/按下
sbit S1 = P0^5;
// 1/0=未按/按下
//定义显示灯
sbit LED3 = P0^2;
// 1/0=灭/亮
sbit LED2 = P0^1;
// 1/0=灭/亮
sbit LED1 = P0^0;
// 1/0=灭/亮
//定义I/O口方向
#define p0dir0xf0// P0.0-P0.2为输出,P0.5-P0.7为输入,
#define p1dir0x02// P1.0(TXD)输出,P1.1(RXD)为输入,
uint8_t data_buf[10] = {0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A};
/**************************************************
功能:延时子程序
说明:用户可随意设定
**************************************************/
void
delay(uint16_t x)
{
uint16_t i,j;
for
(i=0;i<x;i++)
{
j=108;
while
(j--);
}
}
/**************************************************
功能:串口初始化子程序
说明:波特率19.2K,使用内部波特率发生器
**************************************************/
void
uart_init(
void
)
{
ES0 = 0;
// 关UART0中断
REN0 = 1;
// 允许接收
SM0 = 0;
// 串口模式1,8bit可变波特率
SM1 = 1;
PCON |= 0x80;
// SMOD = 1
WDCON |= 0x80;
// 选择内部波特率发生器
S0RELL = 0xe6;
// 波特率19.2K(十进制998=十六进制0x03e6)
S0RELH = 0x03;
TI0 = 0;
// 清发送完成标志
S0BUF=0x99;
// 送初值
}
/**************************************************
功能:串口数据发送子程序
**************************************************/
void
uart_putchar(uint8_t x)
{
while
(!TI0);
// 等待发送完成
TI0=0;
// 清发送完成标志
S0BUF=x;
// 发送数据
}
/**************************************************
功能:NVM多字节擦除/写入子程序
说明:先擦除所在页,然后写入数据
**************************************************/
void
hal_flash_bytes_write(uint16_t a, uint8_t *p, uint16_t n)
{
uint8_t xdata *data pb;
if
((a>=0xfa00)&&(a<=0xffff))
// NVM地址区为0xFA00至0xFFFF
{
F0 = EA;
EA = 0;
// 关中断
WEN = 1;
// 允许写入
if
((a>=0xfa00)&&(a<0xfc00))
// 地址在NVM加长寿命区
{
FCR = 32;
// 必须擦除整页(512byte)!
while
(RDYN == 1);
FCR = 33;
while
(RDYN == 1);
}
if
((a>=0xfc00)&&(a<0xfe00))
// 地址在NVM普通寿命区
{
FCR = 34;
// 擦除整页
while
(RDYN == 1);
}
if
((a>=0xfe00)&&(a<=0xffff))
// 地址在NVM普通寿命区
{
FCR = 35;
// 擦除整页
while
(RDYN == 1);
}
delay(1000);
uart_putchar(XBYTE[a+0]);
// 擦除完成,读出正确应全为“0xFF”
uart_putchar(XBYTE[a+1]);
uart_putchar(XBYTE[a+2]);
uart_putchar(XBYTE[a+3]);
uart_putchar(XBYTE[a+4]);
pb = (uint8_t xdata *)a;
while
(n--)
// 连续写入数据
{
*pb++ = *p++;
while
(RDYN == 1);
}
WEN = 0;
// 写完,禁止写
EA = F0;
// 恢复中断
}
}
/**************************************************
功能:主程序
说明:按下S2键,执行擦除/写入程序,串口显示擦除前和写入后的单元内容
**************************************************/
void
main(
void
)
{
uint16_t addr;
P0DIR = p0dir;
// 设定I/O口输入输出
P1DIR = p1dir;
LED1=LED2=LED3=0;
// 灯全亮
delay(1000);
LED1=LED2=LED3=1;
// 灯全灭
uart_init();
// 串口初始化
addr=0xfb80;
// 设定地址在NVM
while
(1)
{
if
(!S2)
{
LED2=0;
uart_putchar(XBYTE[addr+0]);
// 读原来的NVM内容
uart_putchar(XBYTE[addr+1]);
uart_putchar(XBYTE[addr+2]);
uart_putchar(XBYTE[addr+3]);
uart_putchar(XBYTE[addr+4]);
hal_flash_bytes_write(addr,data_buf,5);
// 改写5个单元
uart_putchar(XBYTE[addr+0]);
// 读改写后的内容
uart_putchar(XBYTE[addr+1]);
uart_putchar(XBYTE[addr+2]);
uart_putchar(XBYTE[addr+3]);
uart_putchar(XBYTE[addr+4]);
// 正确为“0x81,0x82...0x85”
delay(5000);
while
(!S2);
LED2=1;
}
}
}