#include "config.h"
#include <stdio.h>
#define BEEP 1 << 7 // P0.7控制蜂鸣器BEEP
#define LEDS8 0xFF << 18 // P1[25:18]控制LED8~LED1,低电平点亮
#define HC595_CS (1 << 29) // P0.29口为74HC595的片选
#define KEY1 1 << 16 // P0.16连接KEY1
#define KEY2 1 << 17 // P0.17连接KEY2
#define KEY3 1 << 18 // P0.18连接KEY3
#define KEY4 1 << 19 // P0.19连接KEY4
#define KEY5 1 << 20 // P0.20连接KEY5
#define KEY6 1 << 21 // P0.21连接KEY6
char INFO[] = {"Hello EasyARM2131!\
这是EasyARM2131板的演示程序,您将看到8个LED逐个点亮,最后全部熄灭;\
数码管轮流显示0~F字样;\
蜂鸣器鸣叫,表示RTC正在运行。\
按KEY1~KEY6中的任意键,可以看到AD转换的结果;\
调整电位器W1,再次观察,可以看到结果会改变;\
按键的同时,LED会点亮:LED1~LED6分别对应KEY1~KEY6。 "};
uint8 counter = 0;
/*
*********************************************************************************************************
** 函数名称 :DelayNS()
** 函数功能 :长软件延时
*********************************************************************************************************
*/
void DelayNS (uint32 dly)
{
uint32 i;
for ( ; dly>0; dly--)
for (i=0; i<50000; i++);
}
/*
*********************************************************************************************************
** 函数名称:MSPI_Init()
** 函数功能:初始化SPI接口,设置为主机。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************
*/
void MSPI_Init(void)
{
//PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00001500; // 设置管脚连接SPI
PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x15 << 8) ;
SPCCR = 0x52; // 设置SPI时钟分频
SPCR = (0 << 3) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样
(1 << 4) | // CPOL = 1, SCK 为低有效
(1 << 5) | // MSTR = 1, SPI 处于主模式
(0 << 6) | // LSBF = 0, SPI 数据传输MSB (位7)在先
(0 << 7); // SPIE = 0, SPI 中断被禁止
}
/*
*********************************************************************************************************
** 函数名称:MSPI_SendData()
** 函数功能:向SPI总线发送数据。
** 入口参数:data 待发送的数据
** 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8 MSPI_SendData(uint8 data)
{
IO0CLR = HC595_CS; // 片选74HC595
SPI_SPDR = data;
while( 0 == (SPI_SPSR & 0x80)); // 等待SPIF置位,即等待数据发送完毕
IO0SET = HC595_CS;
return(SPI_SPDR);
}
/* 此表为LED0~F以及L、P的字模 */
uint8 const DISP_TAB[19] = {
// 0 1 2 3 4 5 6 7 8 9
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,
// A b C d E F
0x88, 0x83, 0xC6, 0xA1,0x86, 0x8E,
// L P C
0xC7, 0x8C,0xC6 };
#define UART_BPS 115200 // 串口通讯波特率
/*
*********************************************************************************************************
** 函数名称 :UART0_Init()
** 函数功能 :串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率115200。
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_Init (void)
{
uint16 Fdiv;
PINSEL0 = (PINSEL0 & (~0x0F)) | 0x05; // 设置I/O连接到UART0
U0LCR = 0x83; // DLAB=1,允许设置波特率
Fdiv = (Fpclk / 16) / UART_BPS; // 设置波特率
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03;
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendByte()
** 函数功能 :向串口发送字节数据,并等待发送完毕,查询方式。
** 入口参数 :dat 要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendByte (uint8 dat)
{
U0THR = dat;
while ((U0LSR & 0x40) == 0); // 等待数据发送完毕
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendStr()
** 函数功能 :向串口发送一字符串
** 入口参数 :str 要发送的字符串的指针
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendStr (char *str)
{
while (1)
{
if (*str == '\0') break; // 遇到结束符,退出
UART0_SendByte(*str++); // 发送数据
}
}
/*
*******************************************************************************************************
** 函数名称 :RTCInit()
** 函数功能 :初始化实时时钟
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************************
*/
void RTCInit (void)
{
PREINT = Fpclk / 32768 - 1; // 设置基准时钟分频器
PREFRAC = Fpclk - (Fpclk / 32768) * 32768;
CCR = 0x10; // 禁止时间计数器
YEAR = 2005;
MONTH = 01;
DOM = 10;
DOW = 4;
HOUR = 8;
MIN = 30;
SEC = 59;
CIIR = 0x01; // 设置秒值的增量产生1次中断
CCR = 0x11; // 选择独立的外部振荡器,启动RTC
}
/*
*********************************************************************************************************
**
*********************************************************************************************************
*/
void __irq RTC_int (void)
{
counter++;
if(counter>16) counter=0;
if ((IO0SET & BEEP) == 0) IO0SET = BEEP;
else IO0CLR = BEEP;
MSPI_SendData(DISP_TAB[counter]); // 数码管显示
ILR = 0x03; // 清除中断标志
VICVectAddr = 0x00; // VIC结束
}
/*
*********************************************************************************************************
** 函数名称 :main()
** 函数功能 :EasyARM2131开发板出厂演示程序。
** 测试说明 :
*********************************************************************************************************
*/
int main (void)
{
uint8 i;
uint8 key = 0;
uint32 ADC_Data;
char str_key[20];
char str_ad[64];
PINSEL1 |= 1 << 28; // P0.30连接到AD0.3
IO0DIR |= BEEP; // 设置蜂鸣器控制口为输出
IO0SET = BEEP; // 设置蜂鸣器控制口为输出
IO0DIR |= HC595_CS; // 设置74HC595片选控制口为输出
IO1DIR |= LEDS8; // 设置LED控制口为输出
IO0DIR &=~(KEY1|KEY2|KEY3|KEY4|KEY5|KEY6); // KEY1~KEY6控制口输入
/* 打开RTC中断(使用向量中断) */
VICIntSelect = 0x00000000; // 设置所有中断分配为IRQ中断
VICVectCntl1 = 0x20 | 13; // 分配RTC中断到向量中断0
VICVectAddr1 = (uint32)RTC_int; // 设置中断服务程序地址
ILR = 0x03; // 清除RTC中断标志
VICIntEnable = 1 << 13; // 使能RTC中断
IRQEnable(); // 打开中断
MSPI_Init(); // 初始化SPI接口
UART0_Init(); // 串口初始化
RTCInit(); // RTC初始化
UART0_SendStr(INFO); // 向串口发送字符串
for (i=0; i<8; i++)
{
IO1SET = ~(LEDS8 & (1 << (18+i))); // LED显示
DelayNS(30);
IO1CLR = LEDS8 & (1 << (18+i));
DelayNS(30);
}
/* 进行ADC模块设置 */
AD0CR = (1 << 3) | // SEL=8,选择通道3
((Fpclk / 1000000 - 1) << 8) | // CLKDIV=Fpclk/1000000-1,转换时钟为1MHz
(0 << 16) | // BURST=0,软件控制转换操作
(0 << 17) | // CLKS=0, 使用11clock转换
(1 << 21) | // PDN=1,正常工作模式
(0 << 22) | // TEST1:0=00,正常工作模式
(1 << 24) | // START=1,直接启动ADC转换
(0 << 27); // 直接启动ADC转换时,此位无效
DelayNS(10);
ADC_Data = AD0DR; // 读取ADC结果,并清除DONE标志位
//--------------------------------------------------------------------------------------------------
// 测试按键、LED、数码管
//--------------------------------------------------------------------------------------------------
while (1)
{
if ((IO0PIN & KEY1) == 0) // 如果KEY1按下
{
ke