原理图和流程图
流程图:

原理图:

串口通信
使用计时器1和串口中断
注:串口中断参考shihengrui同学的帖子
首先是 Timer1 和 uart0 的初始化:
void Timer1Init(){
CKCON0 |= CKCON0_T1M__SYSCLK;
/**
* Mode 2, 8-bit Counter/Timer with Auto-Reload
*/
TMOD = TMOD | TMOD_T1M__MODE2 | TMOD_CT1__TIMER | TMOD_GATE1__DISABLED;
TCON &= ~TCON_TR1__BMASK; // STOP Timer1
TH1 = 0xFF-(SYSCLK/UART0_BAUD)/2; // 波特率设置卡了好久
TCON = TCON| TCON_TR1__RUN; // START Timer1
}
void uartInit(){
// time1
Timer1Init();
// 9位失效 | 允许接收
// SCON0_MCE__MULTI_DISABLED |
SCON0 = SCON0 | SCON0_REN__RECEIVE_ENABLED;
P0MDIN = P0MDIN | P0MDIN_B4__DIGITAL | P0MDIN_B5__DIGITAL ; // 设置 P0.4 0.5 输入模式
P0MDOUT = P0MDOUT_B4__PUSH_PULL | P0MDOUT_B5__OPEN_DRAIN; // 设置 P0.4 0.5 输出模式
XBR0 = XBR0|XBR0_URT0E__ENABLED;
IE = IE | IE_ES0__ENABLED;
}中断函数,把收到的消息存到结构体 UART_RX 中
#define RX_BUF_MAX_LEN 32
typedef struct
{
uint8_t rx_buff[RX_BUF_MAX_LEN];
uint8_t len;
} URAT_RX;
/*******************************************************************************
Function: // UART0_IRQn
Description: // 串口0中断函数
Input: // 无
Return: // 无
*******************************************************************************/
SI_INTERRUPT(UART0_ISR, UART0_IRQn)
{
if (SCON0_TI == 1) // Check if transmit flag is set
{
tx_flag = 1;
SCON0_TI = 0; // Clear interrupt flag
}
if (SCON0_RI == 1)
{
uart0.rx_buff[uart0.len++] = SBUF0;
if (uart0.len == RX_BUF_MAX_LEN)
uart0.len = 0;
uart0.rx_buff[uart0.len]='\0';
SCON0_RI = 0;
}
}发送数据和清空数据(其实就是len置0,数据写结束符 \0)
void uartSend(char *buf)
{
uint8_t count = 0;
SCON0_TI = 0;
while (buf[count] != '\0')
{
tx_flag = 0;
SBUF0 = buf[count];
while (!tx_flag)
;
count++;
}
for(count=0; count<uart0.len; count++)
{
tx_flag = 0;
SBUF0 = uart0.rx_buff[count];
while (!tx_flag)
;
}
}
void uartClearBuf(){
uart0.len=0;
uart0.rx_buff[0]='\0';
}消息处理函数,用了回调,就可以根据不同消息来进行不同的响应
/**
* 消息处理函数
* @param str
* @param func
* @param all 类型,1则全等,0则模糊查询
*/
void msgHandler(char *str, void(*func)(void), char all){
bool flag = false;
if(all==1){
flag = strcmp(uart0.rx_buff, str)==0;
}else{
flag = strstr(uart0.rx_buff, str)!=NULL;
}
if(flag){
func();
uartClearBuf();
}
}
void funcLed0(){
P1_B4 = 0;
}
void funcLed1(){
P1_B4 = 1;
}消息函数使用示例如下: 当消息内容匹配为 LED1/LED0 时点亮和熄灭板载LED (进行串口点灯),当消息内容里面存在 clear 字符串时,清空消息
msgHandler("LED1", funcLed1, 1);
msgHandler("LED0", funcLed0, 1);
msgHandler("clear", uartClearBuf, 0);驱动步进电机
使用 ULN2003驱动板来驱动步进电机28BYJ-48,使用四个IO口发送步进数据即可
void motorInit(){
P1MDIN = P1MDIN | P1MDIN_B0__DIGITAL | P1MDIN_B1__DIGITAL | P1MDIN_B2__DIGITAL | P1MDIN_B3__DIGITAL; // 设置 P1.0~3 输入模式
P1MDOUT = P1MDOUT | P1MDOUT_B0__PUSH_PULL | P1MDOUT_B1__PUSH_PULL | P1MDOUT_B2__PUSH_PULL | P1MDOUT_B3__PUSH_PULL; // 设置 P1.0~3 输出模式
}
void motorStep(uint8_t step, uint8_t dir)
{
uint8_t temp=step;
if(dir==0) //如果为逆时针旋转
temp=7-step;//调换节拍信号
switch(temp)//8 个节拍控制:A->AB->B->BC->C->CD->D->DA
{
case 0: P1_B0=1;P1_B1=0;P1_B2=0;P1_B3=0;break;
case 1: P1_B0=1;P1_B1=1;P1_B2=0;P1_B3=0;break;
case 2: P1_B0=0;P1_B1=1;P1_B2=0;P1_B3=0;break;
case 3: P1_B0=0;P1_B1=1;P1_B2=1;P1_B3=0;break;
case 4: P1_B0=0;P1_B1=0;P1_B2=1;P1_B3=0;break;
case 5: P1_B0=0;P1_B1=0;P1_B2=1;P1_B3=1;break;
case 6: P1_B0=0;P1_B1=0;P1_B2=0;P1_B3=1;break;
case 7: P1_B0=1;P1_B1=0;P1_B2=0;P1_B3=1;break;
}
}红外遥控
本打算使用外部中断来接收信号,处理不同按键数据,不小心把线碰掉,重新插上接反了,烧了接收器。(这仅有的接收器还是一块51学习板上拔的)后续工作无法进行了,只能等年后买接收器了。
先把外部中断代码贴上来
void iredInit(){
P0_B3=1;
P0MDOUT |= P0MDOUT_B3__SHIFT;
P0MDIN |= P0MDIN_B3__DIGITAL;
// 控制位:int0 边沿触发
TCON |= TCON_IT1__EDGE;
// 低电位有效 | 设置P0.3为int0的中断IO
IT01CF = IT01CF_IN1PL__ACTIVE_LOW | IT01CF_IN1SL__P0_3;
IE |= IE_EX1__ENABLED;
}
SI_INTERRUPT(INT1_ISR, INT1_IRQn)
{
P1_B4 = !P1_B4;
}效果就是,遥控有按键,P0.3收到中断信号,板载LED会亮灭切换。
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |
我要赚赏金打赏帖 |
|
|---|---|
| Chaos-nano:专为低资源单片机设计的轻量级协作式异步操作系统(ATMEGA328P轻量级操作系统)—— 详细介绍被打赏¥16元 | |
| FPGA配置被打赏¥10元 | |
| Chaos-nano协作式异步操作系统:赋能MicrochipAVR8位单片机的革新之路被打赏¥15元 | |
| 基于esp32开发时串口工具的注意点被打赏¥24元 | |
| 基于FireBeetle2ESP32-C5开发板的舵机控制被打赏¥20元 | |
| 【分享开发笔记,赚取电动螺丝刀】MAX78000开发板制作的电子相册被打赏¥32元 | |
| 基于FireBeetle2ESP32-C5开发板的超声波测距及显示被打赏¥21元 | |
| FireBeetle2ESP32-C5上RTC电子时钟的实现被打赏¥25元 | |
| 【分享开发笔记,赚取电动螺丝刀】MAX78000开发板读取SD卡被打赏¥23元 | |
| 【S32K3XX】Standby RAM 重启后数据异常问题调查被打赏¥38元 | |