📄 bsp.c
字号:
U1THR = byte;
while ((U1LSR&0x20)==0) ;
}*/
/*
*--------------------------------------------------------------------------------------------------
* 串口0发送一串, 使用本身的 FIFO 进行发送, 减少中断次数
*--------------------------------------------------------------------------------------------------
*/
void UART0_putstr(unsigned char const *str)
{
unsigned char i, finished=0;
while (1) {
for (i=0; i<14; i++) {
if (*str=='\0') { finished = 1; break; }
U0THR = *str++;
}
if (i) while (!(U0LSR&0x20)) ;
if (finished) break;
}
}
/*
*--------------------------------------------------------------------------------------------------
* 串口1发送一串
*--------------------------------------------------------------------------------------------------
*/
/*void UART1_putstr(unsigned char const *str)
{
while (1) {
if (*str=='\0') break;
UART1_putchar(*str++);
}
}*/
/*}}}PART_3*/
/*{{{PART_4, SPI相关*/
/*
*--------------------------------------------------------------------------------------------------
* Hexok 板上七段数码管由 SPI 接出
*--------------------------------------------------------------------------------------------------
*/
void SPI_Init(void)
{
PINSEL0 |= 0x00001500; // 设置SPI管脚连接
PINSEL0 &= ~(3<<14);
IODIR0 |= (unsigned long)(1<<nDSEN);
PINSEL2 &= ~(1<<3);
IODIR1 |= (0x0F<<DIS1);
IOSET1 |= (0x0F<<DIS1);
S0SPCCR = 0x52; // 设置SPI时钟分频
S0SPCR = (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 中断被禁止
}
/*
*--------------------------------------------------------------------------------------------------
*--------------------------------------------------------------------------------------------------
*/
void SPI_SendData(unsigned char pdata)
{
IOCLR0 |= (unsigned long)(1<<nDSEN); // 片选74HC595
S0SPDR = pdata;
while ((S0SPSR & 0x80)==0); // 等待SPIF置位,即等待数据发送完毕
IOSET0 |= (unsigned long)(1<<nDSEN);
}
/*
*--------------------------------------------------------------------------------------------------
* A H G F E D C B A LED value H G F E D C B A LED value
* ---------- 1 1 0 0 0 0 0 0 '0' 0xC0 1 0 0 0 1 0 0 0 'A' 0x88
* | \ | / | 1 1 1 1 1 0 0 1 '1' 0xF9 1 0 0 0 0 0 1 1 'b' 0x83
* F| \ | / |B 1 0 1 0 0 1 0 0 '2' 0xA4 1 1 0 0 0 1 1 0 'C' 0xC6
* | | 1 0 1 1 0 0 0 0 '3' 0xB0 1 0 1 0 0 0 0 1 'd' 0xA1
* -----G----- 1 0 0 1 1 0 0 1 '4' 0x99 1 0 0 0 0 1 1 0 'E' 0x86
* | | 1 0 0 1 0 0 1 0 '5' 0x92 1 0 0 0 1 1 1 0 'F' 0x8E
* E| / | \ |C 1 0 0 0 0 0 1 0 '6' 0x82
* | / | \ | _ 1 1 1 1 1 0 0 0 '7' 0xF8 0 1 1 1 1 0 0 0 '7.' 0x78
* ----------- | | H 1 0 0 0 0 0 0 0 '8' 0x80 0 0 0 0 0 0 0 0 '8.' 0x00
* D - 1 0 0 1 0 0 0 0 '9' 0x90 0 0 0 1 0 0 0 0 '9.' 0x10
*--------------------------------------------------------------------------------------------------
*/
const unsigned char DISP_TAB[16] = {
/*0 1 2 3 4 5 6 7 8 9 A b C d E F*/
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
/*
*--------------------------------------------------------------------------------------------------
* 显示4位整数,需动态刷新,且不能大于10000
*--------------------------------------------------------------------------------------------------
*/
void DispNumber(unsigned short x)
{
unsigned char tmp;
IOSET1 |= (0x0F<<DIS1);
tmp = DISP_TAB[x/1000];
SPI_SendData(tmp); //显示千位数
IOCLR1 |= (1<<(DIS4));
vTaskDelay(_2ms);
IOSET1 |= (0x0F<<DIS1);
x %= 1000; tmp = DISP_TAB[x/100];
SPI_SendData(tmp);
IOCLR1 |= (1<<(DIS3));
vTaskDelay(_2ms);
IOSET1 |= (0x0F<<DIS1);
x %= 100; tmp = DISP_TAB[x/10];
SPI_SendData(tmp);
IOCLR1 |= (1<<(DIS2));
vTaskDelay(_2ms);
IOSET1 |= (0x0F<<DIS1);
x %= 10; tmp = DISP_TAB[x];
SPI_SendData(tmp);
IOCLR1 |= (1<<(DIS1));
vTaskDelay(_2ms);
}
/*
*--------------------------------------------------------------------------------------------------
* 显示1位整数,无需动态刷新
*--------------------------------------------------------------------------------------------------
*/
/*void DispNumber4(unsigned short x)
{
IOSET1 |= (0x0F<<DIS1);
SPI_SendData(DISP_TAB[x]); //显示千位数
IOCLR1 |= (1<<(DIS4));
}*/
/*}}}PART_4*/
///*{{{PART_5, I2C相关*/
//
//volatile unsigned char I2C_sla; // I2C器件从地址
//volatile unsigned long I2C_suba; // I2C器件内部子地址
//volatile unsigned char I2C_suba_num; // I2C子地址字节数
//volatile unsigned char *I2C_buf; // 数据缓冲区指针
//volatile unsigned long I2C_num; // 要读取/写入的数据个数
//volatile unsigned char I2C_end; // I2C总线结束标志:结束总线是置1
//volatile unsigned char I2C_suba_en; // 子地址控制。0--子地址已处理或不需要 1--读操作 2--写操作
//
///*
//*--------------------------------------------------------------------------------------------------
//*--------------------------------------------------------------------------------------------------
//*/
//void I2C_Init(void)
//{
// const unsigned long Fi2c=100000; // 小于等于 400 kHz
//
// PINSEL0 = (PINSEL0&0xFFFFFF0F)|0x50; // 配置P0.2为SCL, P0.3为SDA
// //NSEL0 = (PINSEL0&(~0xF0))|0x50; // 不影响其它管脚连接
// I20SCLH = (Fpclk/Fi2c+1)/2; // 设定I2C时钟频率(100kbps)
// I20SCLL = (Fpclk/Fi2c+0)/2;
// I20CONCLR = 0x2C;
// I20CONSET = 0x40; // 使能主I2C
//}
//
///*
//*--------------------------------------------------------------------------------------------------
//* 注意处理子地址为2字节的情况。
//*--------------------------------------------------------------------------------------------------
//*/
//void I2C_ISR(void) __attribute__ ((interrupt("IRQ")));
//void I2C_ISR(void)
//{
// switch (I20STAT&0xF8) { // 根据状态码进行相应的处理
// case 0x08: // 已发送起始条件 主发送和主接收都有 装入SLA+W或者SLA+R
// if(I2C_suba_en == 1) { // SLA+R // 指定子地址读
// I20DAT = I2C_sla & 0xFE; // 先写入地址
// } else { // SLA+W
// I20DAT = I2C_sla; // 否则直接发送从机地址
// }
// I20CONCLR = (1 << 3)| // SI
// (1 << 5); // STA
// break;
//
// case 0x10://已发送重复起始条件 主发送和主接收都有 装入SLA+W或者SLA+R
// I20DAT = I2C_sla; // 重起总线后,重发从地址
// I20CONCLR = 0x28; // 清零SI,STA
// break;
//
// case 0x18:
// case 0x28:// 已发送I20DAT中的数据,已接收ACK
// if (I2C_suba_en == 0) {
// if (I2C_num > 0) {
// I20DAT = *I2C_buf++;
// I20CONCLR = 0x28; // 清零SI,STA
// I2C_num--;
// } else { // 没有数据发送了 // 停止总线
// I20CONSET = (1 << 4); // STO
// I20CONCLR = 0x28; // 清零SI,STA
// I2C_end = 1; // 总线已经停止
// }
// }
//
// if(I2C_suba_en == 1) { // 若是指定地址读,则重新启动总线
// if (I2C_suba_num == 2) {
// I20DAT = ((I2C_suba >> 8) & 0xff);
// I20CONCLR = 0x28; // 清零SI,STA
// I2C_suba_num--;
// break;
// }
//
// if(I2C_suba_num == 1) {
// I20DAT = (I2C_suba & 0xff);
// I20CONCLR = 0x28; // 清零SI,STA
// I2C_suba_num--;
// break;
// }
//
// if (I2C_suba_num == 0) {
// I20CONSET = 0x20;
// I20CONCLR = 0x08;
// I2C_suba_en = 0; // 子地址己处理
// break;
// }
// }
//
// if (I2C_suba_en == 2) { // 指定子地址写,子地址尚未指定,则发送子地址
// if (I2C_suba_num > 0) {
// if (I2C_suba_num == 2) {
// I20DAT = ((I2C_suba >> 8) & 0xff);
// I20CONCLR = 0x28;
// I2C_suba_num--;
// break;
// }
// if (I2C_suba_num == 1) {
// I20DAT = (I2C_suba & 0xff);
// I20CONCLR = 0x28;
// I2C_suba_num--;
// I2C_suba_en = 0;
// break;
// }
// }
// }
// break;
//
// case 0x40:// 已发送SLA+R,已接收ACK
// if (I2C_num <= 1) { // 如果是最后一个字节
// I20CONCLR = 1 << 2; // 下次发送非应答信号
// } else {
// I20CONSET = 1 << 2; // 下次发送应答信号
// }
// I20CONCLR = 0x28; // 清零SI,STA
// break;
//
// case 0x20: // 已发送SLA+W,已接收非应答
// case 0x30: // 已发送I20DAT中的数据,已接收非应答
// case 0x38: // 在SLA+R/W或数据字节中丢失仲裁
// case 0x48: // 已发送SLA+R,已接收非应答
// I20CONCLR = 0x28;
// I2C_end = 0xFF;
// break;
//
// case 0x50: // 已接收数据字节,已返回ACK
// *I2C_buf++ = I20DAT;
// I2C_num--;
// if (I2C_num == 1) { // 接收最后一个字节
// I20CONCLR = 0x2C; // STA,SI,AA = 0
// } else {
// I20CONSET = 0x04; // AA=1
// I20CONCLR = 0x28;
// }
// break;
//
// case 0x58: // 已接收数据字节,已返回非应答
// *I2C_buf++ = I20DAT; // 读取最后一字节数据
// I20CONSET = 0x10; // 结束总线
// I20CONCLR = 0x28;
// I2C_end = 1;
// break;
//
// default: break;
// }
// VICVectAddr = 0x00; // 中断处理结束
//}
//
///*}}}PART_5*/
/*{{{PART_6, ADC相关*/
/*
*--------------------------------------------------------------------------------------------------
*--------------------------------------------------------------------------------------------------
*/
void ADC_Init(void)
{
PINSEL1 |= (1<<24); // P0.28连接到AD0.1
AD0CR = (1 << 1); // SEL=8,选择通道1
AD0CR |= ((Fpclk/500000-1)<<8); // CLKDIV=Fpclk/1000000-1,转换时钟为1MHz
//0CR |= (0 << 16); // BURST=0,软件控制转换操作
//0CR |= (0 << 17); // CLKS=0, 使用11clock转换
AD0CR |= (1 << 21); // PDN=1,正常工作模式
//0CR |= (0 << 22); // TEST1:0=00,正常工作模式
AD0CR |= (1 << 24); // START=1,直接启动ADC转换
//0CR |= (0 << 27); // 直接启动ADC转换时,此位无效
}
/*
*--------------------------------------------------------------------------------------------------
*--------------------------------------------------------------------------------------------------
*/
void ADC0_read(unsigned long *ADC_Data)
{
while (!(AD0GDR&0x80000000)) ; // 等待转换结束
*ADC_Data = AD0GDR;
*ADC_Data = (*ADC_Data>>6)&0x03FF; // 读取ADC结果
AD0CR |= 1 << 24; // 再启动转换
}
/*}}}PART_6*/
/*=============================================<EOF>=============================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -