📄 main.cpp
字号:
}
//inline
void UartObj::puthex(signed short val)
{
char str[9];
BinToHex(val, str);
putstr(str);//
}
//static
const unsigned char BintHexTab[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
//inline
void UartObj::BinToHex(unsigned char val, char str[])
{
str[0] = BintHexTab[val >> 4];
str[1] = BintHexTab[val & 0x0f];
str[2] = 0;
}
//inline
void UartObj::BinToHex(unsigned short val, char str[])
{
str[0] = BintHexTab[val >> 12];
str[1] = BintHexTab[(val >> 8) & 0x0f];
str[2] = BintHexTab[(val >> 4) & 0x0f];
str[3] = BintHexTab[val & 0x0f];
str[4] = 0;
}
//inline
void UartObj::BinToHex(signed short val, char str[])
{
str[0] = BintHexTab[val >> 28];
str[1] = BintHexTab[(val >> 24) & 0x0f];
str[2] = BintHexTab[(val >> 20) & 0x0f];
str[3] = BintHexTab[(val >> 16) & 0x0f];
str[4] = BintHexTab[(val >> 12) & 0x0f];
str[5] = BintHexTab[(val >> 8) & 0x0f];
str[6] = BintHexTab[(val >> 4) & 0x0f];
str[7] = BintHexTab[val & 0x0f];
str[8] = 0;
}
RtcObj::RtcObj(void){
RtcInit();//rtc初始化
}
void RtcObj::RtcInit(void){
POWER->P_CONP |= (1 << PCRTC);
RTC->RTC_CCR = 0;
RTC->RTC_CIIR = (1 << IMSEC); // 设置秒值的增量产生一次中断
RTC->RTC_ILR = (1 << RTCALF) | (1 << RTCCIF); // 清除RTC增量和报警中断标志
RTC->RTC_CCR = (1 << CLKEN) | (1 << CLKSRC); // 启动RTC
if (SystemRamTest != SystemRamTestVal) {//RAM真正掉电后才清除时钟!!!
}
}
/*----------------------------------------------------------------------------------------
0000年~9999年星期算法
-----------------------------------------------------------------------------------------*/
unsigned int RtcObj::GetDow(unsigned int y, unsigned int m, unsigned int d)
{
unsigned int w, c;
if (m <= 2){
m |= 4;//1月2月同5月六月表
y--;
}
c = y / 100;
c &= 0x03;//百年%4
y %= 100;
w = ((c | (c << 2)) + (y + (y >> 2)) + (13 * m + 8)/ 5 + d) % 7;//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7
return w;//返回星期
}
/*----------------------------------------------------------------------------------------
0000年~9999年月最大天数算法
-----------------------------------------------------------------------------------------*/
unsigned int RtcObj::GetDom(unsigned int y, unsigned int m)
{
unsigned int dn;
dn = GetDow(y, m + 1, 1) - GetDow(y, m, 1);//m+1=13表示明年的1月
if (dn >= 0x80) dn += 7;
return dn + 28;//返回当月的最大天数
}
nRFObj::nRFObj(void)
{
SpiInit();
nRFInit();
}
void nRFObj::nRFInit(void)
{
PINSEL->PIN_SEL0 |= (P0_15_EINT2 << P0_15_PINSEL); //设置I/O连接到EINT2
nRFPORT->IODIR |= (__1 << nRF_CS) | (__1 << PWR_UP) | (__1 << TX_EN) | (__1 << TRX_CE);
nRFPORT->IOSET = (__1 << nRF_CS) | //关闭SPI
(__1 << PWR_UP); //nRF905上电
nRFPORT->IOCLR = (__1 << TRX_CE) | //设置nRF905为待机方式
(__1 << TX_EN); //设置接收方式
INTCON->EXT_POLAR |= (1 << EXTPOLAR2); //INT2为高电平有效
INTCON->EXT_MODE |= (1 << EXTMODE2); //设置INT2为边沿触发
WritenRFConfig(0);
SetRxMode();//设置接收模式
}
void nRFObj::SpiInit(void)
{
POWER->P_CONP |= (1 << PCSPI0);
PINSEL->PIN_SEL0 |= ((P0_4_SCK0 << P0_4_PINSEL) | (P0_5_MISO0 << P0_5_PINSEL) | (P0_6_MOSI0 << P0_6_PINSEL));
SPI->SPI_SPCCR = 0x52; // 设置SPI时钟分频
SPI->SPI_SPCR = (0x08 << 8) |
(0 << CPHA) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样
(0 << CPOL) | // CPOL = 0, SCK 为低有效
(1 << MSTR) | // MSTR = 1, SPI 处于主模式
(0 << LSBF) | // LSBF = 0, SPI 数据传输MSB (位7)在先
(0 << SPIE); // SPIE = 0, SPI 中断被禁止
}
unsigned char nRFObj::SpiReadWrite(unsigned char cData)
{
SPI->SPI_SPDR = cData; //发送数据(相当于51的SBUF = DATA)
while(!(SPI->SPI_SPSR & (1 << SPIF))); // 等待SPIF置位,即等待数据发送完毕
cData = SPI->SPI_SPDR;
return cData;
}
unsigned char nRFObj::ReadStatus(void)
{
unsigned char val;
nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
val = SpiReadWrite(RC);//读状态
nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
return val;//返回nRF905状态字
}
void nRFObj::SetTxMode(void)//设置发送模式
{
__nop();///
__nop();///
__nop();///
nRFPORT->IOSET = (__1 << TX_EN);
/// __nop();///???5*11.0592M需要以下几个__nop()
_delay_loop_(1);
/*
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
*/
nRFPORT->IOCLR = (__1 << TRX_CE);//设置nRF905为待机方式
/// _delay_loop_(10);
//650uS
__nop();///
__nop();///
__nop();///
}
void nRFObj::SetRxMode(void)//设置接收模式
{
__nop();
__nop();
__nop();
nRFPORT->IOCLR = (__1 << TX_EN);
__nop();
/// _delay_loop_(1);
nRFPORT->IOSET = (__1 << TRX_CE);
/// _delay_loop_(10);
//650uS
__nop();
__nop();
__nop();
}
void nRFObj::StartTx(void)
{
__nop();
__nop();
__nop();
/// _delay_loop_(1);
nRFPORT->IOSET = (__1 << TRX_CE);
/// _delay_loop_(10);
__nop();
__nop();
__nop();
/*
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
*/
nRFPORT->IOCLR = (__1 << TRX_CE);
/// _delay_loop_(1);
__nop();
__nop();
__nop();
}
void nRFObj::WritenRFConfig(unsigned int nRFAddr)//配置nRF905
{
nRFPORT->IOCLR = (__1 << TRX_CE);//设置nRF905为待机方式
__nop();
nRFPORT->IOCLR |= (__1 << nRF_CS);
SpiReadWrite(WC); // Write config command
SpiReadWrite(CH_NO_BYTE); //中心频率低8位
SpiReadWrite(PA_PWR_10dBm | HFREQ_PLL_433MHz); //发射+10dBm,发射频率433MHz,中心频率第9位=0
SpiReadWrite(TX_AFW_4BYTE | RX_AFW_4BYTE); //接收地址宽度4字节,发送地址宽度4字节
SpiReadWrite(RX_PW_32BYTE); //接收数据宽度32字节
SpiReadWrite(TX_PW_32BYTE); //发送数据宽度32字节
SpiReadWrite((nRFAddr >> 24) & 0xff); //接收有效地址第1字节
SpiReadWrite((nRFAddr >> 16) & 0xff); //接收有效地址第2字节
SpiReadWrite((nRFAddr >> 8) & 0xff); //接收有效地址第3字节
SpiReadWrite(nRFAddr & 0xff); //接收有效地址第4字节
SpiReadWrite(CRC16_EN | XOF_16MHz); //CRC16模式使能,晶体振荡器频率16MHz
nRFPORT->IOSET |= (__1 << nRF_CS);
if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
nRFPORT->IOCLR = (__1 << TRX_CE);
}
else {
nRFPORT->IOSET = (__1 << TRX_CE);
}
}
void nRFObj::nRFReadBuffers(void)//收发无线读写模块
{
SetRxMode();//设置接收模式
if (!(nRFPORT->IOSET & (__1 << TX_EN))) {//在接收状态
if ((nRFPORT->IOPIN & (1 << nRF_CD)) || (nRFPORT->IOPIN & (1 << nRF_AM))) {//正确收到数据
nRFPORT->IOCLR = (__1 << TRX_CE);//设置nRF905为待机方式
__nop();
/// _delay_loop_(1);
nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
SpiReadWrite(RRP);
for (int i = 0; i < 32; i ++) {
nRFRxBuff[i] = SpiReadWrite(0xff);
}
nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
nRFRxCount = 32;//接收到32个字节的数据
/// _delay_loop_(1);
if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
nRFPORT->IOCLR = (__1 << TRX_CE);
}
else {
nRFPORT->IOSET = (__1 << TRX_CE);
}
os_evt_set (3888, Lcd_Task);
}
}
}
void nRFObj::nRFWriteBuffers(void)//收发无线读写模块
{
nRF.SetTxMode();//设置发送模式
if (nRFPORT->IOSET & (__1 << TX_EN)) {//在发送状态
if (!((nRFPORT->IOPIN & (1 << nRF_CD)) || (nRFPORT->IOPIN & (1 << nRF_AM)))) {
nRFPORT->IOCLR = (__1 << TRX_CE);//设置nRF905为待机方式
__nop();
/// _delay_loop_(1);
nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
SpiReadWrite(WTA);//写发送地址
for (int i = 0; i < 4; i ++) {
SpiReadWrite( nRFTxBuff[i]);
}
nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
__nop();
/// _delay_loop_(1);
nRFPORT->IOCLR = (__1 << nRF_CS);//打开SPI
SpiReadWrite(WTP);// Write payload command
for (int i = 0; i < 32; i ++) {
SpiReadWrite( nRFTxBuff[i]);
}
nRFPORT->IOSET = (__1 << nRF_CS);//关闭SPI
/// _delay_loop_(1);
nRFTxCount = 32;//接收到32个字节的数据
if (nRFPORT->IOSET & (__1 << TX_EN)) {//再回到原来的无线收发模式
nRFPORT->IOCLR = (__1 << TRX_CE);
}
else {
nRFPORT->IOSET = (__1 << TRX_CE);
}
}
}
}
void MainTask (void) __task {
// Uart.puts("12345678");
// tmr1 = os_tmr_create (10, 1);
Main_Task = os_tsk_self ();
os_tsk_prio_self(3);
Key_Task = os_tsk_create (KeyTask, 10);//创建KeyTask任务及级别
Beep_Task = os_tsk_create (BeepTask, 100);//10创建BeepTask任务及级别
Rtc_Task = os_tsk_create (RtcTask, 100);//创建RtcTask任务及级别
Uart_Task = os_tsk_create (UartTask, 100);//10创建UartTask任务及级别
Gps_Task = os_tsk_create (GpsTask, 10);//创建GpsTask任务及级别
Nrf_Task = os_tsk_create (NrfTask, 10);//10创建NrfTask任务及级别
Lcd_Task = os_tsk_create (LcdTask, 100);//创建LcdTask任务及级别
if (::SystemRamTest != SystemRamTestVal) {
// os_evt_set (DefBeep_Start, Beep_Task);//开关BEEP
os_evt_set (DefBeep_3, Beep_Task);//蜂鸣器发1声
::SystemRamTest = SystemRamTestVal;
}
else {
os_evt_set (DefBeep_2, Beep_Task);//蜂鸣器发2声
// os_evt_set (DefBeep_Begin, Beep_Task);//开关BEEP
}
os_evt_set (1, Lcd_Task);//LCD
//VIC->SoftInt = (1 << VICIntSel_UART0);
VIC->IntEnable = (1 << VICIntSel_EINT0) | //使能EINT0中断
(1 << VICIntSel_EINT2) | //使能EINT2中断
(1 << VICIntSel_RTC) | //使能RTC中断
(1 << VICIntSel_UART0);//使能UART0中断
for (;;) {
if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
else WDPORT->IOSET = (1 << WDI);
os_tsk_pass();
// os_tsk_delete_self();
}
}
void KeyTask (void) __task {
//unsigned char KeyVal;
os_itv_set(10);//每个节拍醒来一次
for (;;) {
os_itv_wait();//
if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
else WDPORT->IOSET = (1 << WDI);
// for (int i = 0; i < 10; i ++) {
// Key.Exec();//键扫描及运行
// }
// os_evt_set (DefBeep_1, Beep_Task);//开关BEEP
}
}
void LcdTask (void) __task {
OS_RESULT result;
OS_RESULT num;
char str[32];
static const char DowTab[8][5] = {
"周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"
};
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待LcdTask任务事件发生
if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
else WDPORT->IOSET = (1 << WDI);
if(result == OS_R_EVT) {
num = os_evt_get();
switch(num) {
case 1://只刷新
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 2://显示时间
// os_evt_set (1, Led_Task);//
Lcd.SetLcdDisplayPos(0, 0);//汉字定位到上行左端
sprintf(str, "今天: %04d-%02d-%02d", Rtc.Year, Rtc.Month, Rtc.Dom);
Lcd.LcdDisplay(str);
Uart.puts(str);
Lcd.SetLcdDisplayPos(1, 0);//汉字定位到上行左端
sprintf(str, "时间%02d:%02d:%02d%4s", Rtc.Hour, Rtc.Min, Rtc.Sec, DowTab[Rtc.Dow & 7]);
Lcd.LcdDisplay(str);
Uart.puts(str);
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 8888:
Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
sprintf(str, "Uart.Status=%02X ", Uart.Status);
Lcd.LcdDisplay(str);
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 1888:
Lcd.SetLcdDisplayPos(3, 0);//汉字定位到上行左端
Lcd.LcdDisplay("改写时间成功!!");
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 2888:
Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
Lcd.LcdDisplay("改写日期成功!!");
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 3888://显示无线数据
Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
Lcd.LcdDisplay(&nRF.nRFRxBuff[0], 8);
Lcd.SetLcdDisplayPos(3, 0);//汉字定位到上行左端
Lcd.LcdDisplay(&nRF.nRFRxBuff[8], 8);
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
break;
case 4888:
Lcd.SetLcdDisplayPos(2, 0);//汉字定位到上行左端
Lcd.LcdDisplay("无线数据发送成功");
Lcd.LcdDisplayBuffer();//刷新LCD显示缓冲区
Uart.puts("无线数据发送成功");
break;
}
}
}
}
void BeepTask (void) __task {
OS_RESULT result;
OS_RESULT num;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待BeepTask任务事件发生
if(result == OS_R_EVT) {
// if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
// else WDPORT->IOSET = (1 << WDI);
Uart.puts("BeepTask任务事件开始");
num = os_evt_get();
while (num > 0){
Uart.puts("BeepTask任务事件发生");
if (num & 1) {
BEEPPORT->IOCLR = (1 << BEEP); // BEEP 蜂鸣
}
else BEEPPORT->IOSET = (1 << BEEP); // BEEP停止蜂鸣
num >>= 1;
os_dly_wait (25);//延时100mS
}
BEEPPORT->IOSET = (1 << BEEP); // BEEP停止蜂鸣
Uart.puts("BeepTask任务事件结束");
}
}
}
void RtcTask (void) __task {
OS_RESULT result;
//OS_RESULT num;
//unsigned int val;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待RtcTask任务事件发生
if (WDPORT->IOSET & (1 << WDI)) WDPORT->IOCLR = (1 << WDI);
else WDPORT->IOSET = (1 << WDI);
if(result == OS_R_EVT) {
// num = os_evt_get();
}
}
}
void UartTask (void) __task {
OS_RESULT result;
OS_RESULT num;
//unsigned int val;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待UartTask任务事件发生
if(result == OS_R_EVT) {
num = os_evt_get();
switch(num) {
case 1://
Uart.LoadDataBuff();
break;
}
}
}
}
void GpsTask (void) __task {
OS_RESULT result;
//OS_RESULT num;
//unsigned int val;
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待GpsTask任务事件发生
if(result == OS_R_EVT) {
// num = os_evt_get();
}
}
}
void NrfTask (void) __task {
OS_RESULT result;
OS_RESULT num;
char str[32];
for (;;) {
result = os_evt_wait_or(0xffff, 0xffff);//等待NrfTask任务事件发生
if(result == OS_R_EVT) {
num = os_evt_get();
switch(num) {
case 250://
sprintf(str, "无线接收事件处理");
Uart.puts(str);
nRF.nRFReadBuffers();
os_evt_set (DefBeep_1, Beep_Task);//蜂鸣器发1声
break;
}
}
}
}
int main (void) {
INTCON->EXT_INT = (1 << EINT0) //清除INT0中断标志
| (1 << EINT1) //清除INT1中断标志
| (1 << EINT2) //清除INT2中断标志
| (1 << EINT3); //清除INT3中断标志
Enable_IRQ();//开中断
os_sys_init (MainTask);//启动ARTX,此函数并不返回main()
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -