📄 io.c
字号:
/*********************************************************************************
* io.C v1.00 SEED-DTK APD的数字IO 实验主程序 *
* 版权(c) 2004- 北京合众达电子技术有限责任公司 *
* 设计者: 耿升辉 *
**********************************************************************************/
#include "string.h"
#include "UART_func.h"
#include "SEED-DEC2407.h"
#include "comm.h"
/*帧长度的设定*/
#define FRAMLONGTH 0x104
#define DataLongth 0x100
#define DCMOTORFORWARD 0x2
#define DCMOTORINVESE 0x1
#define DCMOTORBRAKE 0x03
#define DCMOTORHALT 0x0
typedef struct _UartForDec5416{
unsigned int Length;
unsigned int Type;
unsigned int Mutul;
unsigned int Data[DataLongth];
unsigned int Check;
}UartForDec5416, *PuartForDec5416;
//HANDLE uart_a =0;
PuartForDec5416 precieve =0;
unsigned long i= 0;
unsigned int k= 0;
int uart_s=0,uart_err=0,fifostatus=0;
unsigned long flashbaddr=0;
unsigned long flashaddr = 0;
PuartForDec5416 psend=0;
unsigned int errorsend = 0;
unsigned int uart[0x104] ={0};
unsigned int uarts[0x104] = {0};
void SystemInit(void);
void PHANTOM(void);
void init_UART(void);
int uart_recive(void);
unsigned int uart_send(void);
unsigned int temp;
void delay(int period);
unsigned int mandoit = 1;
void sys_reset(void);
#define EASTEWEST 0x861
#define SOUTHNORTH 0x30c
#define IOCHANGE 0x492
#define ALLFORBIN 0x924
#pragma DATA_SECTION(iostatus,".mysect")
volatile unsigned int iostatus=0;
#pragma DATA_SECTION(p_trafficaddr,".mysect")
/*定义交通灯IO口的地址为0x8000*/
volatile unsigned int* p_trafficaddr=(volatile unsigned int *)0x8000;
#pragma DATA_SECTION(p_ledaddr,".mysect")
/*定义led灯IO口的地址为0x8002*/
volatile unsigned int* p_ledaddr=(volatile unsigned int *)0x8002;
#pragma DATA_SECTION(data0save,".mysect")
unsigned int data0save=0;
void main(void)
{
ONLED;
DINT;
SystemInit();
init_UART();
*IFR = 0x3f;
*IMR = 0x01;
EINT;
/*实验主控程序*/
psend = (PuartForDec5416)(&uarts[0]);
precieve = (PuartForDec5416)(&uart[0]);
/*通知主机,系统准备好*/
psend->Length = FRAMLONGTH;
psend->Type = UARTCOMMAND;
psend->Data[0] = INITOVER;
psend->Mutul = UARTCONT;
uart_send();
for(;;)
{
uart_s =uart_recive();
/* 返回值 0:接受完成 */
/* 1:数据未准备好 */
/* -1:串口接受错误 */
/* 2:中断超时错误 */
/* 3: 较验出错 */
/*串口出错*/
/*接收从主机的数据*/
precieve = (PuartForDec5416)(&uart[0]);
switch(precieve->Data[0])
{
case TRAFFICAUTO:
data0save=precieve->Data[0];
mandoit = 0;
/*白天模式*/
/*从东西到南北*/
iostatus = EASTEWEST;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(2000);
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(1000);
iostatus = SOUTHNORTH;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(8000);
/*从南北到东西*/
iostatus = SOUTHNORTH;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(2000);
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(1000);
iostatus = EASTEWEST;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(8000);
break;
/*人工模式*/
case TRAFFICMANNUL:
precieve->Data[0] = 0;
data0save=0;
mandoit = 1;
iostatus = 0;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(6000);
break;
/*夜间模式*/
case TRAFFICNIGHT:
data0save=precieve->Data[0];
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(6000);
iostatus = 0;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(6000);
break;
/*交通灯东西通*/
case TRAFFICEAST:
if(mandoit == 1)
{
precieve->Data[0] = 0;
data0save=0;
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(1000);
iostatus = EASTEWEST;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(2000);
}
else
{
precieve->Data[0]=data0save;
}
break;
/*交通灯南北通*/
case TRAFFICSOUTH:
if(mandoit == 1)
{
precieve->Data[0] = 0;
data0save=0;
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(1000);
iostatus = SOUTHNORTH;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(2000);
}
else
{
precieve->Data[0]=data0save;
}
break;
/*禁行*/
case TRAFFICFORBID:
if(mandoit == 1)
{
precieve->Data[0] = 0;
data0save=0;
iostatus = IOCHANGE;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(1000);
iostatus = ALLFORBIN;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(2000);
}
else
{
precieve->Data[0]=data0save;
}
break;
/*LED灯控制*/
case IOSET:
precieve->Data[0] = data0save;
iostatus = precieve->Data[1];
CEPAGESELECT = SELECTCE3;
*p_ledaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
break;
/*系统复位*/
case SYSRESET:
precieve->Data[0] = 0;
iostatus = 0;
CEPAGESELECT = SELECTCE3;
*p_trafficaddr=iostatus;
*p_ledaddr=iostatus;
CEPAGESELECT = SELECTSRAM;
delay(100);
sys_reset();
break;
default:
break;
}
}
}
void SystemInit(void)
{
WSGR = 0x1ff;
*WDCR = 0x68;
*SCSR1 = 0x0204;
*MCRA = 0x04;
*XINT1CR = 0x01;
*EVAIFRA = 0xFFFF;
*EVAIMRA = 0x0080;
}
void PHANTOM(void)
{
}
void init_UART(void)
{
UARTA_LCR = (data_w8+data_s1+LC_1_DLAB); /*8位数据 1停止位 不校验 开启除数转换*/
UARTA_DLL = buad_19k2_l; /*9.6K波特率*/
UARTA_DLH = buad_19k2_h;
UARTA_LCR = (data_w8+data_s1+LC_0_DLAB); /*8位数据 1停止位 不校验 关闭其余寄存器转换*/
UARTA_MCR = UartLoop;
UARTA_FCR = fifo_reset;
UARTA_FCR = fifo_enable+fifo_txdip8+fifo_rxdip8;//TRIGLE level =8
UARTA_IER = uartint_rhr;
for(i= 0; i<0x104;i++)
{
uart[i] = 0;
uarts[i] = 0;
}
for(i=0;i<32;i++)
{
sys_statbuff[i]=0;//系统标志buff清0
}
}
interrupt void c_int1(void)//串口接收中断
{
int i;
DINT;
if((*PIVR & 0x01) == 0x01)//xint1中断
{
if((INT1_RD & 0x02) == 0x02)//uarta中断
{
temp=UARTA_LSR;//读一次lsr,第一次读有可能有误。
temp=UARTA_LSR;
for(i=0;i<8;i++)//fifo有8个字节等待读。
{
if (((temp&0x1e)==0)&&((temp&0x01)==1))//无串口接收错误
{
uarta_recbuff[sys_statbuff[RECAADDR]]=UARTA_RHR&0xff;//接收数据
sys_statbuff[RECAADDR]++;
}
else
{
sys_statbuff[UARTAERR]=1;//错误标志为1
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
break;//中止循环
}
}//for(i=0;i<8;i++)//fifo有8个字节等待读
UARTA_FCR = fifo_rreset;//3rest r fifo,enable fifo
if(sys_statbuff[RECAADDR]==FRAMLONGTH*2)//满帧
{
if (sys_statbuff[RECANEW]==1)//上一帧新帧标志仍未清除
{
sys_statbuff[UARTIMEA]=1;//超时错误置一
}
sys_statbuff[RECANEW]=1;//新帧标志置一
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
//转移到uart[]。
for(i=0;i<FRAMLONGTH;i++)
{
uart[i]=(uarta_recbuff[i*2]<<8)+uarta_recbuff[i*2+1];
}
}
if(sys_statbuff[RECAADDR]>FRAMLONGTH*2)//超帧
{
sys_statbuff[UARTAERR]=1;//错误标志为1
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
}
}//if((INT1_RD & 0x02) == 0x02)//uarta中断
} //if((*PIVR & 0x01) == 0x01)//xint1中断
*XINT1CR = *XINT1CR | 0x8000;
*IFR = *IFR & 0x01;
EINT;
}
/* 返回值 0:接受完成 */
/* 1:数据未准备好 */
/* -1:串口接受错误 */
/* 2:中断超时错误 */
/* 3: 较验出错 */
int uart_recive(void)
{
int check;
/*判断串口是否故障*/
if(sys_statbuff[UARTAERR] != 0)
{
sys_statbuff[UARTAERR]=0;
return -1;
}
/*数据未准备好*/
if(sys_statbuff[RECANEW] != 1)
{
return 1;
}
sys_statbuff[RECANEW]=0;//新帧标志位清零
check=0;
for(i=0;i<FRAMLONGTH-1;i++)
{
check=check ^ uart[i];
}
if(check!=uart[FRAMLONGTH-1])//校验不正确
{
return 3;
}
return 0;
}
unsigned int uart_send(void)
{
unsigned int i;
unsigned int send_datah;
unsigned int timeout = 0x4000;
unsigned int check = 0;
for(i = 0; i<FRAMLONGTH-1; i++)
{
for(;;)
{
timeout--;
temp=UARTA_LSR;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的高8位*/
send_datah = uarts[i];
check = check ^ (send_datah);
UARTA_THR = send_datah>>8;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
timeout = 0x4000;
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的低8位*/
UARTA_THR = uarts[i];
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
}
/*发送校验结果*/
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的高8位*/
send_datah = (check>>8);
UARTA_THR = send_datah;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
timeout = 0x4000;
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的低8位*/
UARTA_THR = check;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
uarts[FRAMLONGTH-1]=check;
return 0;
}
void delay(int period)
{
int i, j;
for(i=0; i<period; i++)
{
for(j=0; j<0x40; j++);
}
}
void sys_reset(void)
{
WSGR = 0;
*WDCR = 0x08;
for(;;){};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -