📄 main.cpp
字号:
| VICIntSel_EINT0;//获取EINT0的IRQ级别
VIC->VectCntls[1] = VICIntSel_Enable//使能IRQ中断
| VICIntSel_EINT2;//获取EINT2的IRQ级别
VIC->VectCntls[2] = VICIntSel_Enable//使能IRQ中断
| VICIntSel_RTC;//获取RTC的IRQ级别
VIC->VectCntls[3] = VICIntSel_Enable//使能IRQ中断
| VICIntSel_UART0;//获取UART0的IRQ级别
INTCON->EXT_INT = (1 << EINT0) //清除INT0中断标志
| (1 << EINT1) //清除INT1中断标志
| (1 << EINT2) //清除INT2中断标志
| (1 << EINT3); //清除INT3中断标志
}
void SystemObj::BeepInit(void)
{
BEEPPORT->IODIR |= (1 << BEEP); // 设置BEEP控制口为输出
// BEEPPORT->IOSET = (1 << BEEP); // BEEP停止蜂鸣
BEEPPORT->IOCLR = (1 << BEEP); // BEEP停止蜂鸣
//while(1) {
// WDPORT->IOPIN ^= (1 << WDI); // 设置WDI控制口为输出
//}
}
//__inline
LcdObj::LcdObj(void)
{
LcdPinSetup();
LcdInit();
}
//__inline
void LcdObj::LcdPinSetup(void)
{
/*
POWER->P_CONP |= (1 << PCSPI0);
PINSEL->PIN_SEL0 |= ((P0_4_SCK0 << P0_4_PINSEL) | (P0_6_MOSI0 << P0_6_PINSEL));
// SPI->SPI_SPCCR = 0x168; // 设置SPI时钟分频
SPI->SPI_SPCCR = 0x52; // 设置SPI时钟分频
SPI->SPI_SPCR =
(1 << CPHA) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样
(1 << CPOL) | // CPOL = 1, SCK 为低有效
(1 << MSTR) | // MSTR = 1, SPI 处于主模式
(0 << LSBF) | // LSBF = 0, SPI 数据传输MSB (位7)在先
(0 << SPIE); // SPIE = 0, SPI 中断被禁止
*/
/* 设置MOSI 和SCK 及SS 为输出,其他为输入 */
LCDPORT->IODIR |= (1 << LCDRST) | (1 << LCDCS) | (1 << LCDSCK) | (1 << LCDSID);
LCDPORT->IOCLR = (1 << LCDRST) | (1 << LCDCS);
LCDPORT->IOSET = (1 << LCDSCK) | (1 << LCDSID);
_delay_loop_(10);
LCDPORT->IOSET = (1 << LCDRST);
_delay_loop_(100);
}
//__inline
void LcdObj::LcdInit(void)
{
/*---------------------------------------------------
LCD模块上电等待延时
----------------------------------------------------*/
LcdClearBuffer();
LcdSendCommand(0x20);//发送4位控制命令
// LcdSendCommand(0x30);//发送8位控制命令//与8位4位无关!!!
LcdSendCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0
LcdSendCommand(0x04);//发送进入点命令
LcdSendCommand(0x0c);//发送开显示关光标命令
LcdSendCommand(0x01);//发送清除显示命令
LcdSendCommand(0x80);//发送设定DDRAM地址0x00命令
//汉字0xfd出错测试
LcdDisplay("褒饼昌除待谍洱俘");
SetLcdDisplayPos(1, 0);//汉字定位到上行左端
LcdDisplay("庚过糊积箭烬君魁");
SetLcdDisplayPos(2, 0);//汉字定位到上行左端
LcdDisplay("例笼慢谬凝琵讫驱");
SetLcdDisplayPos(3, 0);//汉字定位到上行左端
LcdDisplay("三升数她听妄锡淆");
}
//__inline
void LcdObj::LcdSend(char cData)
{
unsigned int i;
// _delay_loop_(1);
for (i = 0; i < 8; i ++) {
// _delay_loop_(1);
LCDPORT->IOCLR = (1 << LCDSCK);
// _delay_loop_(1);
if (cData & 0x80) {//MSB最高位为1时
LCDPORT->IOSET = (1 << LCDSID);
}
else {
LCDPORT->IOCLR = (1 << LCDSID);
}
// _delay_loop_(1);
cData <<= 1;
LCDPORT->IOSET = (1 << LCDSCK);
// _delay_loop_(1);
}
/*
SPI->SPI_SPDR = cData; //发送数据(相当于51的SBUF = DATA)
while(!(SPI->SPI_SPSR & (1 << SPIF))); // 等待SPIF置位,即等待数据发送完毕
*/
}
/*--------------------------------------------------------
发送8位LCD控制命令
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendCommand(char cCommand)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
LcdSend(0xf8);//发送LCD控制命令
LcdSend(cCommand & 0xf0);//发送高4位LCD控制命令
LcdSend(cCommand << 4);//发送低4位LCD控制命令
LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
if (cCommand == 0x01) _delay_loop_(160);//1.6mS
else _delay_loop_(72);//st7920要求等待72uS
}
/*--------------------------------------------------------
发送8位LCD显示数据
--------------------------------------------------------*/
//__inline
void LcdObj::LcdSendData(char cData)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
LCDPORT->IOSET = (1 << LCDCS);//SS=1,启动SPI
LcdSend(0xfa);//发送LCD显示数据
LcdSend(cData & 0xf0);//发送高4位LCD显示数据
LcdSend(cData << 4);//发送低4位LCD显示数据
LCDPORT->IOCLR = (1 << LCDCS);//SS=0,关闭SPI
_delay_loop_(72);//st7920要求等待延时72uS
}
//__inline
void LcdObj::SetLcdDisplayPos(unsigned char row, unsigned char col)
{
row &= 0x03;//4行汉字
col &= 0x0f;//每行8个汉字16个字符
LcdRow = row;
LcdCol = col;
LcdRowWriteEnable[row] = 1;//允许此行刷新汉字显示
}
//__inline
void LcdObj::LcdClearBuffer(void)
{
unsigned char i, j;
for (i = 0;i < 4;i ++) {
for (j = 0;j < 16; j ++) {
LcdBuffer[i][j] = ' ';
}
LcdRowWriteEnable[i] = 1;//允许此行刷新汉字显示
}
LcdRow = 0;
LcdCol = 0;
}
//__inline
void LcdObj::LcdDisplayBuffer(void)
{
unsigned char i, j;
for (i = 0; i < 4; i ++) {//4行汉字
if (LcdRowWriteEnable[i]) {//允许此行刷新汉字显示
LcdSendCommand(0x80 + (i & 1) * 16 + (i >> 1) * 8);//移动光标
for (j = 0; j < 16; j ++) {//每行8个汉字16个字符
LcdSendData(LcdBuffer[i][j]);//刷新显示字符
}
LcdRowWriteEnable[i] = 0;//过后不允许此行刷新汉字显示
}
}
}
//__inline
void LcdObj::LcdDisplay(const char * string)
{
while(*string) {
LcdBuffer[LcdRow][LcdCol ++] = *string ++;
}
}
void LcdObj::LcdDisplay(unsigned char hexstr[], unsigned int len)
{
unsigned char ch;
for (int i = 0; i < len; i ++) {
ch = *hexstr++;
if (ch < 0xa0) {
LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) + '0';
}
else {
LcdBuffer[LcdRow][LcdCol ++] = (ch >> 4) - 10 + 'A';
}
if ((ch & 0x0f) < 0x0a) {
LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) + '0';
}
else {
LcdBuffer[LcdRow][LcdCol ++] = (ch & 0x0f) - 10 + 'A';
}
}
}
//__inline//(不敢加inline)
//__forceinline
void LcdObj::LcdDisplay(unsigned int Val, unsigned char size1, signed char size0)
{
char str[7], *ptr;
unsigned char i;
ptr = str + 5;
if (size0 > 0) {//有小数
for (i = 0; i < 3; i ++) {
*ptr -- = (Val % 10) + '0';
Val /= 10;
}
ptr[size0 + 1] = 0;
*ptr -- = '.';
}
else {
*ptr -- = 0;
}
for (i = 0; i < size1; i ++) {
if (i && (Val == 0)) {
if (size0 < 0) {
*ptr -- = '0';
}
else {
*ptr -- = ' ';
}
}
else *ptr -- = (Val % 10) + '0';
Val /= 10;
}
LcdDisplay(ptr + 1);
}
//inline
UartObj::UartObj(void)
{
UartInit();
}
//inline
void UartObj::UartInit(void)
{
unsigned int Fdiv;
PINSEL->PIN_SEL0 |= (P0_0_TXD0 << P0_0_PINSEL) | (P0_1_RXD0 << P0_1_PINSEL); //设置I/O连接到UART0
U0->LCR = 0x83; // DLAB=1,允许设置波特率
Fdiv = (Fpclk / 16) / UART_BPS; // 设置波特率
U0->DLM = Fdiv / 256;
U0->DLL = Fdiv % 256;
U0->LCR = 0x03;
U0->FCR = 0xc7; /* 初始化FIFO 接收14个字节就中断*/
U0->IER = 0x07;//0x01;//0x07 /* 允许接收发送中断 */
RxCount = TxCount = 0;
RxdCount = TxdCount = 0;
for (int i = 0; i < 256; i ++) {
RxBuffer[i] = TxBuffer[i] = 0;
}
TxBusy = false;
//
}
void UartObj::Exec(void)
{
static unsigned char cData = 0;
unsigned char ch;
Status = U0->IIR & 0x0f;
switch (Status) {
case 0x06://接收线状态
switch (U0->LSR) {
case 0x63:
break;
}
break;
case 0x04://接收数据可用
case 0x0c://字符超时指示
do{
ch = U0->RBR;
if (ch == '$') {
cData = '$';
RxBuffer[RxCount ++] = ch;
}
else if(cData == '$'){
if (ch >= 0x20) {
RxBuffer[RxCount ++] = ch;
}
else if (ch == 0x0d) {
RxBuffer[RxCount ++] = ch;
}
else if (ch == 0x0a) {
// if (RxBuffer[(RxCount - 1) & 0x7f] == 0x0d) {
cData = 0;
RxBuffer[RxCount ++] = ch;
//isr_evt_set (DefBeep_1, Beep_Task);
isr_evt_set (1, Uart_Task);
// }
}
}
}while(U0->LSR & (1 << RDR));
break;
case 0x01://LPCARM保留中断,可用于软件模拟激活UART0中断
if (!(VIC->SoftInt & (1 << VICIntSel_UART0))) {//硬件UART0中断
break;//正常的UART0中断退出
}
case 0x02://THRE中断
TxBusy = TxCount != TxdCount;//保证FIFO发送全部结束时,缓冲区空不拒绝发送
for (int i = 0; (i < 16) && (TxCount != TxdCount); i ++) {//1次写入FIFO最多16个字节
ch = TxBuffer[TxdCount ++];//取出缓冲区1个字节数据
if (ch >= 0x0a) {//防止非法字符漏入
U0->THR = ch;//将缓冲区1个字节数据写入FIFO
}
}
break;
// case 0x0f://保留中断
// break;
}
}
/*
RTC->RTC_YEAR = 2006;
RTC->RTC_MONTH = 3;
RTC->RTC_DOM = 30;
RTC->RTC_HOUR =8;
RTC->RTC_MIN =53;
RTC->RTC_SEC = 0;
RTC->RTC_DOW = 4;
*/
void UartObj::LoadDataBuff(void)
{
unsigned char ch, cl;
unsigned int val;
if (RxBuffer[RxdCount ++] == '$') {
ch = RxBuffer[RxdCount ++];//取PC命令
switch(ch) {
case 'C'://$CS81*CRC<CR>
ch = RxBuffer[RxdCount ++];//取PC命令
switch(ch) {
case 'S'://系统日期
if (RxBuffer[RxdCount + 2] == 0x0a) {
/// nRF.SetTxMode();//设置发送模式
/// os_dly_wait(1);
for (int i = 0; i < 32; i ++) {
nRF.nRFTxBuff[i] = nRF.nRFRxBuff[i];
}
for (int i = 0; i < 4; i ++) {
nRF.nRFTxBuff[i] = nRF.nRFRxBuff[i + 4];
}
for (int i = 0; i < 4; i ++) {
nRF.nRFTxBuff[i + 4] = nRF.nRFRxBuff[i];
}
ch = RxBuffer[RxdCount ++];
cl = RxBuffer[RxdCount ++];
val = ((ch - '0') << 4) + (cl - '0');
nRF.nRFTxBuff[9] = val;//无线命令号
nRF.nRFWriteBuffers();
// nRF.StartTx();//开始发送//?????
/// os_dly_wait(1);
nRF.SetRxMode();//设置接收模式
// RxdCount ++;//放弃0x0d
RxdCount ++;//放弃0x0a
os_evt_set (4888, Lcd_Task);//开关BEEP
os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
}
break;
}
break;
case 'D'://$DS2006-03-18*CRC<CR>
ch = RxBuffer[RxdCount ++];//取PC命令
switch(ch) {
case 'S'://系统日期
if (RxBuffer[RxdCount + 10] == 0x0a) {
RTC->RTC_CCR = 0;
val = 0;
for (int i = 0; i < 4; i ++) {
ch = RxBuffer[RxdCount ++];
val = val * 10 + (ch - '0');
}
RTC->RTC_YEAR = val;
RxdCount ++;//放弃'-'
val = 0;
for (int i = 0; i < 2; i ++) {
ch = RxBuffer[RxdCount ++];
val = val * 10 + (ch - '0');
}
RTC->RTC_MONTH = val;
RxdCount ++;//放弃'-'
val = 0;
for (int i = 0; i < 2; i ++) {
ch = RxBuffer[RxdCount ++];
val = val * 10 + (ch - '0');
}
RTC->RTC_DOM = val;
/*
RxdCount ++;//放弃'-'
val = 0;
for (int i = 0; i < 1; i ++) {
RxdCount &= 0x7f;
ch = RxBuffer[RxdCount ++];
val = val * 10 + (ch - '0');
}
*/
val = Rtc.GetDow(RTC->RTC_YEAR, RTC->RTC_MONTH, RTC->RTC_DOM);
RTC->RTC_DOW = val;
// RxdCount ++;//放弃0x0d
RxdCount ++;//放弃0x0a
RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC); // 启动RTC
os_evt_set (2888, Lcd_Task);//开关BEEP
os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
}
else {
RxdCount = RxCount;//失败,取下次首指针
}
break;
}
break;
case 'T'://$TS00:01:08*CRC<CR>
ch = RxBuffer[RxdCount ++];//取PC命令
switch(ch) {
case 'S'://系统时间
if (RxBuffer[RxdCount + 8] == 0x0a) {
RTC->RTC_CCR = 0;
ch = RxBuffer[RxdCount ++];
val = (ch - '0') * 10;
ch = RxBuffer[RxdCount ++];
val += ch - '0';
RTC->RTC_HOUR = val;
RxdCount ++;//放弃':'
ch = RxBuffer[RxdCount ++];
val = (ch - '0') * 10;
ch = RxBuffer[RxdCount ++];
val += ch - '0';
RTC->RTC_MIN = val;
RxdCount ++;//放弃':'
ch = RxBuffer[RxdCount ++];
val = (ch - '0') * 10;
ch = RxBuffer[RxdCount ++];
val += ch - '0';
RTC->RTC_SEC = val;
// RxdCount ++;//放弃0x0d
RxdCount ++;//放弃0x0a
RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC); // 启动RTC
os_evt_set (1888, Lcd_Task);//开关BEEP
os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
}
else {
RxdCount = RxCount;//失败,取下次首指针
}
break;
}
break;
}
}
else {
RxdCount = RxCount;//失败,取下次首指针
}
}
//inline
void UartObj::putchar(unsigned char dat)
{
// U0->THR = dat;
// while ((U0->LSR & 0x40) == 0); // 等待数据发送完毕
//以上未用FIFO
//以下采用FIFO...
TxBuffer[TxCount ++] = dat;//写入发送缓冲区(并非FIFO!!!)
if ((!TxBusy) && (dat == 0x0a)){//发送FIFO不忙并且以换行符为界
VIC->SoftInt = (1 << VICIntSel_UART0);//软件中断模拟激活UART0中断
}
}
//inline
void UartObj::putstr(const char str[])
{
while (*str) {
putchar(*str);
str++;
}
}
//inline
void UartObj::puts(const char str[])
{
while (*str) {
putchar(*str);
str++;
}
putchar(0x0d);
putchar(0x0a);//回车换行
}
//inline
void UartObj::puthex(unsigned char val)
{
char str[3];
BinToHex(val, str);
putstr(str);//
}
//inline
void UartObj::puthex(unsigned short val)
{
char str[5];
BinToHex(val, str);
putstr(str);//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -