这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【EFM8BB52单片机】宠物小用具,猫咪逗猫棒(初步完结)

共30条 2/3 1 2 3 跳转至
助工
2022-01-17 00:08:53     打赏
11楼

原理图和流程图

流程图:

原理图:




专家
2022-01-17 00:19:02     打赏
12楼

感谢楼主分享


高工
2022-01-17 00:51:35     打赏
13楼

很厉害


专家
2022-01-17 01:51:35     打赏
14楼

看看


助工
2022-01-19 08:26:56     打赏
15楼

串口通信

使用计时器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);



院士
2022-01-19 08:31:26     打赏
16楼

挺不错的


助工
2022-01-19 08:31:31     打赏
17楼

驱动步进电机

使用 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;
  }
}



助工
2022-01-19 08:37:39     打赏
18楼

红外遥控

本打算使用外部中断来接收信号,处理不同按键数据,不小心把线碰掉,重新插上接反了,烧了接收器。(这仅有的接收器还是一块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会亮灭切换。



专家
2022-01-19 08:42:48     打赏
19楼

学习


院士
2022-01-19 08:44:12     打赏
20楼

谢谢分享


共30条 2/3 1 2 3 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]