共2条
1/1 1 跳转至页
lpc2132 俺写的lpc2132的串口驱动(中断方式)
问
#include "lpc213x.h"
#include "Includes.h"
#define BIT(x) (1<<x)
#define SET_BIT(x, y) (x|=(1<<y))
#define CLR_BIT(x, y) (x&=~(1<<y))
#define GET_BIT(x, y) (x&(1<<y))
volatile struct
{
INT8U rd_buf[32];
INT8U td_buf[2048];
INT16U rd_max;
INT16U td_max;
INT16U rd_cnt;
INT16U td_cnt;
} uart0;
OS_EVENT *uart0_rd_ok;
OS_EVENT *uart0_td_ok;
extern void UART0_Handler(void);
void UART0_Exception(void)
{
unsigned char i, k;
k = U0IIR&0x0F;
switch(k)
{
case 0x02:
for (i=0; i<16; i++)
{
if (uart0.td_cnt < uart0.td_max)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
}
else
{
U0IER = U0IER & (~0x02);
OSSemPost(uart0_td_ok);
goto UART0_Exception_RET;
}
}
break;
case 0x04:
for (i=0; i<8; i++)
{
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0_rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
}
break;
case 0x0C:
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0_rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
break;
default:
break;
}
UART0_Exception_RET:
VICVectAddr = 0x00;
}
void UART0_init(void)
{
INT16U i;
for (i=0; i<32; i++)
{
uart0.rd_buf[i] = 0x00;
}
for (i=0; i<2048; i++)
{
uart0.td_buf[i] = (unsigned char)i;
}
uart0.rd_max = 8;
uart0.td_max = 0;
uart0.rd_cnt = 0;
uart0.td_cnt = 0;
SET_BIT(PINSEL0, 0);
CLR_BIT(PINSEL0, 1);
SET_BIT(PINSEL0, 2);
CLR_BIT(PINSEL0, 3);
U0LCR = 0x83;
U0DLL = 0x06;
U0DLM = 0x00;
U0LCR = 0x03;
U0FCR = 0x87;
U0IER = 0x01;
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x26;
VICVectAddr1 = (unsigned long)UART0_Handler;
VICIntEnable = (1<<6);
}
void UART0_putc(unsigned char c)
{
U0THR = c;
while ((U0LSR&0x40) == 0)
{
}
}
void UART0_puts(char *p)
{
while(*p)
{
UART0_putc(*p);
p++;
}
}
void UART0_send(INT16U len)
{
//unsigned short i;
//for (i=0; i<len; i++)
//{
// UART0_putc(uart0.td_buf[i]);
//}
uart0.td_cnt = 0;
uart0.td_max = len;
if (uart0.td_max > 0)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
U0IER = U0IER | 0x02; /* 允许发送中断 */
}
}
void UART0_task(void *pdata)
{
INT8U err;
pdata = pdata;
uart0_rd_ok = OSSemCreate(0);
uart0_td_ok = OSSemCreate(0);
UART0_init();
do
{
OSSemPend(uart0_rd_ok, 0, &err);
UART0_send(1024);
OSSemPend(uart0_td_ok, 0, &err);
uart0.rd_cnt = 0;
} while(1);
}
答 1: 谢谢啦中断看了几天都不明白,这下好了,虽然我的是2104 答 2: 在多任务中,串口驱动,当一个设备想使用串口时,必须保证当时串口是空闲,如果不空闲,必须等待,直到空间,或者指定时间内串口设备未空闲,提示信息,
楼上的串口驱动采用结构,比较不错
但是要是用在多任何中,如果用多个任何使用此串口,估计会有问题 答 3: 采用信号量太占用资源,不如用 Uart0Status=OSFlagCreate表示状态,另外,其实完全可以将串口的忙闲状态等信息一块封装在结构中,这样不断模块化,同时,一个状态只占用一个信息, 答 4: 呵呵,改了一下
#include "lpc213x.h"
#include "Includes.h"
#define BIT(x) (1<<x)
#define SET_BIT(x, y) (x|=(1<<y))
#define CLR_BIT(x, y) (x&=~(1<<y))
#define GET_BIT(x, y) (x&(1<<y))
volatile struct
{
INT8U rd_buf[32];
INT8U td_buf[2048];
INT16U rd_max;
INT16U td_max;
INT16U rd_cnt;
INT16U td_cnt;
OS_EVENT *rd_ok;
OS_EVENT *td_ok;
} uart0;
extern void UART0_Handler(void);
void UART0_Exception(void)
{
unsigned char i, k;
k = U0IIR&0x0F;
switch(k)
{
case 0x02:
for (i=0; i<16; i++)
{
if (uart0.td_cnt < uart0.td_max)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
}
else
{
U0IER = U0IER & (~0x02);
OSSemPost(uart0.td_ok);
goto UART0_Exception_RET;
}
}
break;
case 0x04:
for (i=0; i<8; i++)
{
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0.rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
}
break;
case 0x0C:
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0.rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
break;
default:
break;
}
UART0_Exception_RET:
VICVectAddr = 0x00;
}
void UART0_init(void)
{
INT16U i;
for (i=0; i<32; i++)
{
uart0.rd_buf[i] = 0x00;
}
for (i=0; i<2048; i++)
{
uart0.td_buf[i] = (unsigned char)i;
}
uart0.rd_max = 8;
uart0.td_max = 0;
uart0.rd_cnt = 0;
uart0.td_cnt = 0;
uart0.rd_ok = OSSemCreate(0);
uart0.td_ok = OSSemCreate(0);
SET_BIT(PINSEL0, 0);
CLR_BIT(PINSEL0, 1);
SET_BIT(PINSEL0, 2);
CLR_BIT(PINSEL0, 3);
U0LCR = 0x83;
U0DLL = 0x06;
U0DLM = 0x00;
U0LCR = 0x03;
U0FCR = 0x87;
U0IER = 0x01;
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x26;
VICVectAddr1 = (unsigned long)UART0_Handler;
VICIntEnable = (1<<6);
}
void UART0_putc(unsigned char c)
{
U0THR = c;
while ((U0LSR&0x40) == 0)
{
}
}
void UART0_puts(char *p)
{
while(*p)
{
UART0_putc(*p);
p++;
}
}
void UART0_send(INT16U len)
{
uart0.td_cnt = 0;
uart0.td_max = len;
if (uart0.td_max > 0)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
U0IER = U0IER | 0x02;
}
}
void UART0_task(void *pdata)
{
INT8U err;
pdata = pdata;
UART0_init();
do
{
OSSemPend(uart0.rd_ok, 0, &err);
UART0_send(1024);
OSSemPend(uart0.td_ok, 0, &err);
uart0.rd_cnt = 0;
} while(1);
}
答 5: 好,一直想用双串口的驱动
#include "lpc213x.h"
#include "Includes.h"
#define BIT(x) (1<<x)
#define SET_BIT(x, y) (x|=(1<<y))
#define CLR_BIT(x, y) (x&=~(1<<y))
#define GET_BIT(x, y) (x&(1<<y))
volatile struct
{
INT8U rd_buf[32];
INT8U td_buf[2048];
INT16U rd_max;
INT16U td_max;
INT16U rd_cnt;
INT16U td_cnt;
} uart0;
OS_EVENT *uart0_rd_ok;
OS_EVENT *uart0_td_ok;
extern void UART0_Handler(void);
void UART0_Exception(void)
{
unsigned char i, k;
k = U0IIR&0x0F;
switch(k)
{
case 0x02:
for (i=0; i<16; i++)
{
if (uart0.td_cnt < uart0.td_max)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
}
else
{
U0IER = U0IER & (~0x02);
OSSemPost(uart0_td_ok);
goto UART0_Exception_RET;
}
}
break;
case 0x04:
for (i=0; i<8; i++)
{
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0_rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
}
break;
case 0x0C:
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0_rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
break;
default:
break;
}
UART0_Exception_RET:
VICVectAddr = 0x00;
}
void UART0_init(void)
{
INT16U i;
for (i=0; i<32; i++)
{
uart0.rd_buf[i] = 0x00;
}
for (i=0; i<2048; i++)
{
uart0.td_buf[i] = (unsigned char)i;
}
uart0.rd_max = 8;
uart0.td_max = 0;
uart0.rd_cnt = 0;
uart0.td_cnt = 0;
SET_BIT(PINSEL0, 0);
CLR_BIT(PINSEL0, 1);
SET_BIT(PINSEL0, 2);
CLR_BIT(PINSEL0, 3);
U0LCR = 0x83;
U0DLL = 0x06;
U0DLM = 0x00;
U0LCR = 0x03;
U0FCR = 0x87;
U0IER = 0x01;
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x26;
VICVectAddr1 = (unsigned long)UART0_Handler;
VICIntEnable = (1<<6);
}
void UART0_putc(unsigned char c)
{
U0THR = c;
while ((U0LSR&0x40) == 0)
{
}
}
void UART0_puts(char *p)
{
while(*p)
{
UART0_putc(*p);
p++;
}
}
void UART0_send(INT16U len)
{
//unsigned short i;
//for (i=0; i<len; i++)
//{
// UART0_putc(uart0.td_buf[i]);
//}
uart0.td_cnt = 0;
uart0.td_max = len;
if (uart0.td_max > 0)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
U0IER = U0IER | 0x02; /* 允许发送中断 */
}
}
void UART0_task(void *pdata)
{
INT8U err;
pdata = pdata;
uart0_rd_ok = OSSemCreate(0);
uart0_td_ok = OSSemCreate(0);
UART0_init();
do
{
OSSemPend(uart0_rd_ok, 0, &err);
UART0_send(1024);
OSSemPend(uart0_td_ok, 0, &err);
uart0.rd_cnt = 0;
} while(1);
}
答 1: 谢谢啦中断看了几天都不明白,这下好了,虽然我的是2104 答 2: 在多任务中,串口驱动,当一个设备想使用串口时,必须保证当时串口是空闲,如果不空闲,必须等待,直到空间,或者指定时间内串口设备未空闲,提示信息,
楼上的串口驱动采用结构,比较不错
但是要是用在多任何中,如果用多个任何使用此串口,估计会有问题 答 3: 采用信号量太占用资源,不如用 Uart0Status=OSFlagCreate表示状态,另外,其实完全可以将串口的忙闲状态等信息一块封装在结构中,这样不断模块化,同时,一个状态只占用一个信息, 答 4: 呵呵,改了一下
#include "lpc213x.h"
#include "Includes.h"
#define BIT(x) (1<<x)
#define SET_BIT(x, y) (x|=(1<<y))
#define CLR_BIT(x, y) (x&=~(1<<y))
#define GET_BIT(x, y) (x&(1<<y))
volatile struct
{
INT8U rd_buf[32];
INT8U td_buf[2048];
INT16U rd_max;
INT16U td_max;
INT16U rd_cnt;
INT16U td_cnt;
OS_EVENT *rd_ok;
OS_EVENT *td_ok;
} uart0;
extern void UART0_Handler(void);
void UART0_Exception(void)
{
unsigned char i, k;
k = U0IIR&0x0F;
switch(k)
{
case 0x02:
for (i=0; i<16; i++)
{
if (uart0.td_cnt < uart0.td_max)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
}
else
{
U0IER = U0IER & (~0x02);
OSSemPost(uart0.td_ok);
goto UART0_Exception_RET;
}
}
break;
case 0x04:
for (i=0; i<8; i++)
{
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0.rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
}
break;
case 0x0C:
uart0.rd_buf[uart0.rd_cnt] = U0RBR;
if (uart0.rd_buf[0] == 0xFD)
{
uart0.rd_cnt++;
if (uart0.rd_cnt == uart0.rd_max)
{
OSSemPost(uart0.rd_ok);
goto UART0_Exception_RET;
}
else if (uart0.rd_cnt > 31)
{
uart0.rd_cnt = 31;
}
}
break;
default:
break;
}
UART0_Exception_RET:
VICVectAddr = 0x00;
}
void UART0_init(void)
{
INT16U i;
for (i=0; i<32; i++)
{
uart0.rd_buf[i] = 0x00;
}
for (i=0; i<2048; i++)
{
uart0.td_buf[i] = (unsigned char)i;
}
uart0.rd_max = 8;
uart0.td_max = 0;
uart0.rd_cnt = 0;
uart0.td_cnt = 0;
uart0.rd_ok = OSSemCreate(0);
uart0.td_ok = OSSemCreate(0);
SET_BIT(PINSEL0, 0);
CLR_BIT(PINSEL0, 1);
SET_BIT(PINSEL0, 2);
CLR_BIT(PINSEL0, 3);
U0LCR = 0x83;
U0DLL = 0x06;
U0DLM = 0x00;
U0LCR = 0x03;
U0FCR = 0x87;
U0IER = 0x01;
VICIntSelect = 0x00000000;
VICVectCntl1 = 0x26;
VICVectAddr1 = (unsigned long)UART0_Handler;
VICIntEnable = (1<<6);
}
void UART0_putc(unsigned char c)
{
U0THR = c;
while ((U0LSR&0x40) == 0)
{
}
}
void UART0_puts(char *p)
{
while(*p)
{
UART0_putc(*p);
p++;
}
}
void UART0_send(INT16U len)
{
uart0.td_cnt = 0;
uart0.td_max = len;
if (uart0.td_max > 0)
{
U0THR = uart0.td_buf[uart0.td_cnt];
uart0.td_cnt++;
U0IER = U0IER | 0x02;
}
}
void UART0_task(void *pdata)
{
INT8U err;
pdata = pdata;
UART0_init();
do
{
OSSemPend(uart0.rd_ok, 0, &err);
UART0_send(1024);
OSSemPend(uart0.td_ok, 0, &err);
uart0.rd_cnt = 0;
} while(1);
}
答 5: 好,一直想用双串口的驱动
共2条
1/1 1 跳转至页
回复
| 有奖活动 | |
|---|---|
| 2026年“我要开发板活动”第三季,开始了! | |
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
我要赚赏金打赏帖 |
|
|---|---|
| 以启明云端ESP32P4开发板实现TF卡读写功能被打赏¥28元 | |
| 【分享开发笔记,赚取电动螺丝刀】树莓派5串口UART0配置被打赏¥25元 | |
| 【STM32F103ZET6】17:分享在Rtos项目中断管理的使用经验被打赏¥23元 | |
| 【STM32F103ZET6】16:分享在中断中恢复串口任务,遇到的问题被打赏¥31元 | |
| 在FireBeetle2ESP32-C5上实现温度大气压检测及显示被打赏¥21元 | |
| 【分享开发笔记,赚取电动螺丝刀】SAME51双串口收发配置被打赏¥27元 | |
| Chaos-nano操作系统在手持式VOC检测设备上的应用被打赏¥37元 | |
| 【分享开发笔记,赚取电动螺丝刀】关于在导入第三方库lib时,wchart类型冲突的原因及解决方案被打赏¥30元 | |
| 在FireBeetle2ESP32-C5上实现温湿度检测和显示被打赏¥20元 | |
| 在FireBeetle2ESP32-C5上实现光照强度检测及显示被打赏¥21元 | |
我要赚赏金
