📄 main.c
字号:
#include "config.h"
#include "main.h"
#include <string.h>
void Delay(uint dly)
{
unsigned int i, m;
for(m = 0; m < dly; m++)
{
for(i=0; i<10000; i++)
;
}
}
/****************************************************************************
* 名称:LED()
* 功能:LED灯闪
* 入口参数:dly
* 出口参数:无
****************************************************************************/
void LED_Light(void)
{
if((IO0PIN & LED) == 0) IO0SET = LED; //LED1灯亮
else IO0CLR = LED;
}
void LED0_Light(void)
{
if((IO0PIN & LED0) == 0) IO0SET = LED0; //LED1灯亮
else IO0CLR = LED0;
}
void LED1_Light(void)
{
if((IO0PIN & LED1) == 0) IO0SET = LED1;
else IO0CLR = LED1;
}
void UART0_LED(void)
{
if((IO0PIN & LED2) == 0) IO0SET = LED2; //LED1灯亮
else IO0CLR = LED2;
}
/*************************中断初始化******************************************
名称:中断初始化
输入参数:无
输出参数:无
功能:中断初始化
******************************************************************************/
void INTERRUPT_Init(void)
{
VICIntSelect = 0x00000000; //所有中断通道设置为IRQ中断
VICIntEnable = 0x00000000; //清除所有中断使能
VICVectCntl0 = 0x00000026; //串口0中断通道分配最高优先级(向量近制器1)
VICVectAddr0 = (uint)UART0_IRQ; //设置UART0向量地址
VICIntEnable |= Interrupt_UART0; //设置串口0中断使能
VICVectCntl1 = 0x00000027; //串口1中断通道分配最高优先级(向量近制器2)
VICDefVectAddr = (uint)TIMER0_IRQ; //设置TIMER0向量地址
VICIntEnable |= Interrupt_TIMER0; //设置TIMER0中断使能
VICVectCntl2 = 0x00000025; //TIMER1中断通道分配最高优先级(向量近制器4)
}
/*************系统时钟初始化****************
*******默认状态下:
PLLCON = 0x00 //PLL控制(使能)寄存器 PLLCON: 0xE01FC080
PLLCFG = 0x00 //PLL配制寄存器 PLLCON: 0xE01FC084
PLLSTAT = 0x00 //PLL状态寄存器 PLLCON: 0xE01FC088
PLLFEED = 0x00 //PLL馈送寄存器 PLLCON: 0xE01FC08c
#define Fosc 11059200 //晶振频率,10MHz~25MHz,应当与实际一至
#define Fcclk (Fosc * 5) //系统频率,必须为Fosc的整数倍(1~32),且<=60MHZ
#define Fcco (Fcclk * 4) //CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz~320MHz
#define Fpclk (Fcclk / 4) * 1 //VPB时钟频率,只能为(Fcclk / 4)的1 ~ 4倍
Fcclk = Fosc * M;
Fcco = Fosc * M * 2 * P
******设置好PLL后,必须对所设置的数据在PLLFEED进行馈送,PLL才能生效
***********************************************/
void PLL_Init(void)
{
uchar m, p;
PLLCON = 1;
#if ((Fcclk / 4) / Fpclk) == 1 //设置串口0波特率的分频为4分频
VPBDIV = 0;
#endif
#if ((Fcclk / 4) / Fpclk) == 2 //设置串口0波特率的分频为2分频
VPBDIV = 2;
#endif
#if ((Fcclk / 4) / Fpclk) == 4 //设置串口0波特率的分频为无分频
VPBDIV = 1;
#endif
m = (Fcclk / Fosc) - 1; //PLL的倍频值
p = (Fcco / Fcclk) / 2; //PLL的分频值
PLLCFG = (p << 5) | (m & 0x1f);
PLLFEED = 0xaa;
PLLFEED = 0x55;
while((PLLSTAT & (1 << 10)) == 0); //锁定PLL值
PLLCON = 3;
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
/*************************系统初始化*****************************************
名称:系统初始化
输入参数:无
输出参数:无
功能:对个个I/0进行初始化,及各个中断初始化
*****************************************************************************/
void SYSTEM_Init(void)
{
uchar k; //设置引脚功能寄存器
PINSEL0 = 0x00051505; //设置串口0及串口1,SPI功能
PINSEL1 = 0x00000000;
IO0DIR = SH485EN | LED | SPIOUT | TXD;
IO0CLR = SH485EN; //设置为接收使能 0x0080 to be low
for(k = 0; k < 2; k++)
{
LED_Light();
Delay(10);
}
}
/*************************定时器0初始化******************************************
名称:定时器0初始化
输入参数:无
输出参数:无
功能:定时器0初始化
实现0.5s;
#define Fosc 11059200 //晶振频率,10MHz~25MHz,应当与实际一至
#define Fcclk (Fosc * 4) //系统频率,必须为Fosc的整数倍(1~32),且<=60MHZ
#define Fcco (Fcclk * 4) //CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz~320MHz
#define Fpclk (Fcclk / 4) //VPB时钟频率,只能为(Fcclk / 4)的1 ~ 4倍
如果所得的值与分频值相等就为1S
********************************************************************************************/
void TIMER0_Init (void)
{
T0PR = 10; //设置定时分频为100分频,得110592Hz
T0MCR = 0x03; //匹配通道0匹配中断并复位T0TC
T0MR0 = 100; //设置MR0比较值,定时0.1mS
T0TCR = 0x03; //启运计时并复位
T0TCR = 0x01; //启动计时
}
/************************定时器0中断*****************************************
名称:定时器0中断
输入参数:无
输出参数:无
功能:定时器0中断
********************************************/
void __irq TIMER0_IRQ(void)
{
unsigned short m;
if(T0IR & 0x01) //表示MR0定时中断
{
T0IR |= 0x01; //清除定时器
if(TIMER0_Flag[0] == TRUE)
{
TIMER0_count[0]++; //清除计数器
if(TIMER0_count[0] >= delay_num)
{
TIMER0_count[0] = 0;
TIMER0_Flag[0] = FALSE;
UART0_RcvOk = TRUE;
UART0_RcvLen = UART0_RcvCount;
for(m = 0; m < UART0_RcvLen; m++)
{
UART0_Rcvbuf[m] = UART0_RcvTempbuf[m];
if(UART0_Rcvbuf[m]==0x03)LED1_Light();
}
UART0_RcvCount = 0;
}
}
if(TIMER0_Flag[1] == TRUE)
{
TIMER0_count[1]++; //清除计数器
if(TIMER0_count[1] >= delay_num)
{
TIMER0_count[1] = 0;
TIMER0_Flag[1] = FALSE;
}
}
}
VICVectAddr = 0x00;
}
/*************************串口0数据处理******************************************
名称:串口0初始化
输入参数:无
输出参数:无
功能:串口0初始化。包括波特,中断使能,FIFO中断设置
******************************************************************************/
/*************************串口0初始化******************************************
名称:串口0初始化
输入参数:无
输出参数:无
功能:串口0初始化。包括波特,中断使能,FIFO中断设置
******************************************************************************/
void UART0_Init (void)
{
uint Fdiv;
U0LCR = 0x83; // DLAB = 1,可设置波特率
Fdiv =(Fpclk/16)/BAUD_RATE;
U0DLL = Fdiv%256;
U0DLM = Fdiv/256;
U0LCR = 0x03;
U0IER = 0x01; //设置串口0的中断使能
U0FCR = 0x01; //使能FIFO,串口接收到1个字节才产生中断
}
/*************************串口0接收中断*****************************************
名称:串口0接收中断
输入参数:无
输出参数:串口0所接收的数据
功能:串口0中断接收数据
******************************************************************************/
void __irq UART0_IRQ(void)
{
uchar IIRValue, LSRValue;
uchar Rcv_data;
IIRValue = U0IIR; //读取中断标识寄存器
Rcv_data = U0RBR; // Dummy read on RX to clear
TIMER0_count[0] = 0; //清除计数器
TIMER0_Flag[0] = TRUE;
IIRValue >>= 1; // skip pending bit in IIR
IIRValue &= 0x07; // check bit 1~3, interrupt identification
if ( IIRValue == IIR_RLS ) // Receive Line Status
{
LSRValue = U0LSR; //读取线状态寄存器 Receive Line Status
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) //判断线状态标志
{
VICVectAddr = 0; //Acknowledge Interrupt
return;
}
if ( LSRValue & LSR_RDR ) // Receive Data Ready
{
UART0_RcvTempbuf[UART0_RcvCount] = Rcv_data;
UART0_RcvCount++;
}
}
else if ( IIRValue == IIR_RDA ) // Receive Data Available
{
UART0_RcvTempbuf[UART0_RcvCount] = Rcv_data;
UART0_RcvCount++;
}
else if ( IIRValue == IIR_CTI ) // Character timeout indicator
{
UART0Status |= 0x100; // Bit 9 as the CTI error 接收超时置位 Character Time-out indicator
}
UART0_LED();
VICVectAddr = 0; // Acknowledge Interrupt
}
/*************************串口0发送单个字节***********************************
名称:串口0发送单个字节
输入参数:要发送的字节
输出参数:无
功能:串口0发送单个字节
******************************************************************************/
void UART0_SendByte ( uchar m)
{
U0THR = m; // 发送数据
while((U0LSR&0x40)==0 ); // 等待数据发送完毕
}
/*************************串口0发送字符串*************************************
名称:串口0发送字符串
输入参数:要发送的字节数组,*buf, 及数组的长度Len
输出参数:无
功能:串口0发送字符串
******************************************************************************/
void UART0_SendString(uint adress, uchar *buf, unsigned short Len)
{
unsigned short i;
U0LCR =0x2b;
Delay(1);
UART0_SendByte(adress);
U0LCR =0x3b;
Delay(1);
for(i = 0; i < Len; i++)
{
UART0_SendByte(buf[i]);
}
IO0CLR = SP485_EN0;
}
/****************************************************************************
**主函数:读取实时时钟的值,并从串口发送出去。
****************************************************************************/
int main(void)
{
uchar Ti[2];
SYSTEM_Init(); //系统初始化
PLL_Init(); //IC工作时钟初始化
UART0_Init(); //串口0初始化
TIMER0_Init(); //定时器0初始化
INTERRUPT_Init(); //中断初始化
Ti[0]=3; Ti[1]=10;
while (1)
{
Delay(500);
UART0_SendString(0x02,Ti,1);
Ti[0]+=Ti[1];
UART0_SendString(0x03,Ti,1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -