📄 main.c
字号:
/*--------------------------------------------------------
ARTX水鸟LPC2131板实验笔记
HotPower@126.com 2006.1.15 03:18 于西安大雁塔村队部
---------------------------------------------------------*/
#include <ARTX.h>
#include <LPC213x.H> // Philips Peripheral Registers
#include <LPC213xDEF.H> //ARM菜鸟HotPower创建定义文件(新版)
#include <main.h>
#include <string.h>
#include <stdio.h>
#pragma NOINIT
#define LcdSSP //LCD硬件用SSP接口
volatile unsigned int SystemRamTest;
LcdData LcdBuffers;
OS_TID Main_Task, Key_Task, Led_Task, Lednum_Task, Beep_Task, Lcd_Task, Adc_Task;
void MainTask (void) __task;
void KeyTask (void) __task;
void LedTask (void) __task;
void LednumTask (void) __task;
void BeepTask (void) __task;
void LcdTask (void) __task;
void AdcTask (void) __task;
void SystemInit(void);
void KeyInit(void);
void LcdInit(void);
void LedInit(void);
void LednumInit(void);
void BeepInit(void);
void AdcInit(void);
void MSPI_Init(void);
unsigned char MSPI_SendData(unsigned char);
void LedDisplay(unsigned char);
void SSP_Init(void);
uint8 SSP_SendData(uint8);
void MSSP_Init(void);
uint8 MSSP_SendData(uint8);
void LcdSendCommand(unsigned char);
void LcdSendData(unsigned char);
void _delay_loop_(unsigned int);
void LcdClearBuffer(void);
void LcdDisplayBuffers(void);
void SetLcdDisplayPos(unsigned char, unsigned char);
void LcdDisplayString(unsigned char []);
uint32 GetAdcVal(unsigned char);
void _delay_loop_(unsigned int val)
{
unsigned int i;
for(i = 0; i < val; i ++);
}
void AdcInit(void)
{
PINSEL1 |= (P0_28_AD0_1 << P0_28_PINSEL);// P0.28连接到AD0.1
PINSEL1 |= (P0_30_AD0_3 << P0_30_PINSEL);// P0.30连接到AD0.3
}
uint32 GetAdcVal(unsigned char Chnum)
{
uint32 ADC_Data;
Chnum &= 0x07;//Adc0~Adc7
/* 进行ADC模块设置 */
AD0CR = (1 << Chnum) | // SEL=8,选择通道3 不加电容 加电容
// ((Fpclk / 1000000 - 1) << 8) | // CLKDIV=Fpclk/1000000-1,转换时钟为1MHz
// ((Fpclk / 2000000 - 1) << 8) | // CLKDIV=Fpclk/2000000-1,转换时钟为500KHz(1.511V~1.395V)
// ((Fpclk / 2500000 - 1) << 8) | // CLKDIV=Fpclk/2500000-1,转换时钟为400KHz(1.508V~1.240V)
// ((Fpclk / 3333333 - 1) << 8) | // CLKDIV=Fpclk/3333333-1,转换时钟为300KHz(1.506V~1.503V)
((Fpclk / 4000000 - 1) << 8) | // CLKDIV=Fpclk/4000000-1,转换时钟为250KHz(1.501V~1.499V)(1.503V~1.508V)
// ((Fpclk / 5000000 - 1) << 8) | // CLKDIV=Fpclk/5000000-1,转换时钟为200KHz(1.508V~1.503V)
// ((Fpclk / 10000000 - 1) << 8) | // CLKDIV=Fpclk/10000000-1,转换时钟为100KHz(1.487V~1.484V)(1.511V~1.513V)
// ((Fpclk / 100000000 - 1) << 8) | // CLKDIV=Fpclk/100000000-1,转换时钟为10KHz(低频不行)
(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转换时,此位无效
_delay_loop_(20);
ADC_Data = AD0DR; // 读取ADC结果,并清除DONE标志位
AD0CR |= 1 << 24; // 进行第一次转换
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
AD0CR |= 1 << 24; // 再次启动转换
//必须2次转换,否则差0.1V~0.2V
while ((AD0DR & 0x80000000) == 0); // 等待转换结束
ADC_Data = AD0DR; // 读取ADC结果
ADC_Data = (ADC_Data >> 6) & 0x3ff;
ADC_Data = ADC_Data * 2480; // 参考电压经过3/4分压
ADC_Data = ADC_Data / 1024;
return ADC_Data;
}
void LcdClearBuffer(void)//清除屏幕
{
unsigned char i, j;
for (i = 0;i < 4;i ++) {
for (j = 0;j < 16; j ++) {
LcdBuffers.LcdBuff[i][j] = ' ';
}
LcdBuffers.LcdBuffWrFlag[i] = 0;
}
}
void LcdInit(void) {
#ifdef LcdSSP
SSP_Init();
#else
MSSP_Init();
#endif
/*---------------------------------------------------
LCD模块上电等待延时
----------------------------------------------------*/
// DelayMs(1000);//上电等待延时1000Ms
os_dly_wait (5);//延时100mS
LcdClearBuffer();
LcdSendCommand(0x20);//发送4位控制命令
LcdSendCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0
LcdSendCommand(0x0c);//发送开显示关光标命令
LcdSendCommand(0x04);//发送进入点命令
LcdSendCommand(0x01);//发送清除显示命令
LcdSendCommand(0x80);//发送设定DDRAM地址0x00命令
// DelayMs(1000);//上电等待延时1000Ms//晕~~~
// SetLcdDisplayPos(0, 0);//汉字定位到上行左端
// LcdDisplayString("汉字显示演示12");
// SetLcdDisplayPos(1, 0);//汉字定位到上行左端
// LcdDisplayString("汉字显示演示34");
SetLcdDisplayPos(2, 0);//汉字定位到上行左端
LcdDisplayString("汉字显示演示56");
SetLcdDisplayPos(3, 0);//汉字定位到上行左端
LcdDisplayString("汉字显示演示78");
os_dly_wait (5);//延时100mS
}
/*--------------------------------------------------------
发送8位LCD控制命令
--------------------------------------------------------*/
void LcdSendCommand(unsigned char cCommand)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
#ifdef LcdSSP
SSP_SendData(0xf8);//发送LCD控制命令
SSP_SendData(cCommand & 0xf0);//发送高4位LCD控制命令
SSP_SendData(cCommand << 4);//发送低4位LCD控制命令
#else
MSSP_SendData(0xf8);//发送LCD控制命令
MSSP_SendData(cCommand & 0xf0);//发送高4位LCD控制命令
MSSP_SendData(cCommand << 4);//发送低4位LCD控制命令
#endif
if (cCommand == 0x01) _delay_loop_(1600);//1.6mS
else _delay_loop_(72);//st7920要求等待72uS
}
/*--------------------------------------------------------
发送8位LCD显示数据
--------------------------------------------------------*/
void LcdSendData(unsigned char cData)
{
/*--------------------------------------------------------
发送同步脉冲11111 WR(0) RS(0) 0发送顺序从左至右)
--------------------------------------------------------*/
#ifdef LcdSSP
SSP_SendData(0xfa);//发送LCD显示数据
SSP_SendData(cData & 0xf0);//发送高4位LCD显示数据
SSP_SendData(cData << 4);//发送低4位LCD显示数据
#else
MSSP_SendData(0xfa);//发送LCD显示数据
MSSP_SendData(cData & 0xf0);//发送高4位LCD显示数据
MSSP_SendData(cData << 4);//发送低4位LCD显示数据
#endif
_delay_loop_(72);//st7920要求等待延时72uS
}
void LcdDisplayBuffers(void)
{
unsigned char i, j;
for (i = 0;i < 4;i ++) {
if (LcdBuffers.LcdBuffWrFlag[i]) {//此行已被改写
LcdSendCommand(0x80 + (i & 1) * 16 + (i >> 1) * 8);
for (j = 0;j < 16; j ++) {
LcdSendData(LcdBuffers.LcdBuff[i][j]);//显示刷新
}
LcdBuffers.LcdBuffWrFlag[i] = 0;
}
}
}
void SetLcdDisplayPos(unsigned char row, unsigned char col)
{
LcdBuffers.Row = row & 0x03;//4行
LcdBuffers.Col = col & 0x0f;//16列
}
void LcdDisplayString(unsigned char string[])
{
char len, i;
len = strlen(string);
if ((LcdBuffers.Row < 4) && ((LcdBuffers.Col + len) <= 16)) {
if (len == 0) {
while(LcdBuffers.Col < 16) LcdBuffers.LcdBuff[LcdBuffers.Row][LcdBuffers.Col ++] = ' ';
}
else
for (i = 0; i < len; i ++) LcdBuffers.LcdBuff[LcdBuffers.Row][LcdBuffers.Col ++] = string[i];
LcdBuffers.LcdBuffWrFlag[LcdBuffers.Row] = 1;//需要显示刷新
}
}
void MSSP_Init(void)
{
IODIR0 |= (1 << SCK1); // 设置SCK0控制口为输出
IODIR0 |= (1 << MOSI1); // 设置MOSI0控制口为输出
}
/*
*********************************************************************************************************
** 函数名称:SSP_Init()
** 函数功能:将SSP控制器设置为主机SPI。
** 入口参数:无
** 出口参数:无
*********************************************************************************************************
*/
void SSP_Init(void)
{
PCONP |= 1<<10;
PINSEL1 |= ((P0_17_SCK1 << P0_17_PINSEL) | (P0_19_MOSI1 << P0_19_PINSEL));
SSPCR0 = (0x01 << 8) | // SCR 设置SPI时钟分频
// (0x01 << 7) | // CPHA 时钟输出相位,仅SPI模式有效
(0x00 << 7) | // CPHA 时钟输出相位,仅SPI模式有效
// (0x01 << 6) | // CPOL 时钟输出极性,仅SPI模式有效
(0x00 << 6) | // CPOL 时钟输出极性,仅SPI模式有效
(0x00 << 4) | // FRF 帧格式 00=SPI,01=SSI,10=Microwire,11=保留
(0x07 << 0); // DSS 数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位
SSPCR1 = (0x00 << 3) | // SOD 从机输出禁能,1=禁止,0=允许
(0x00 << 2) | // MS 主从选择,0=主机,1=从机
(0x01 << 1) | // SSE SSP使能,1=允许SSP与其它设备通信
(0x00 << 0); // LBM 回写模式
SSPCPSR = 0x52; // PCLK分频值
// SSPIMSC = 0x07; // 中断屏蔽寄存器
SSPICR = 0x03; // 中断清除寄存器
}
/*
*********************************************************************************************************
* 函数名称:SSP_SendData()
* 函数功能:SSP接口向SPI总线发送数据。
* 入口参数:data 待发送的数据
* 出口参数:返回值为读取的数据
*********************************************************************************************************
*/
uint8 SSP_SendData(uint8 data)
{
SSPDR = data;
while( (SSPSR & 0x01) == 0 ); // 等待TFE置位,即发送FIFO空
return(SSPDR);
}
uint8 MSSP_SendData(uint8 data)
{
unsigned char i;
// _delay_loop_(1);
for (i = 0; i < 8; i ++) {
// _delay_loop_(1);
IOCLR0 = (1 << SCK1);
// _delay_loop_(1);
if (data & 0x80) {//MSB最高位为1时
IOSET0 = (1 << MOSI1);
}
else {
IOCLR0 = (1 << MOSI1);
}
// _delay_loop_(1);
data <<= 1;
IOSET0 = (1 << SCK1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -