第二十课--串口接收字符串并转化为数组/zh

来自Microduino Wikipedia
1183296105@qq.com讨论 | 贡献2015年1月19日 (一) 08:11的版本 调试
跳转至: 导航搜索

目的

此教程的目的在于将字符串按某种规则转换成数组并赋值。通过串口PWM控制LED灯,串口收到逗号分割的6组数字比如:100,200,300,400,500,600然后在6个PWM端口14, 15, 16, 17, 18, 19输出对应PWM值。

设备

  • Microduino-CoreSTM32/zh
  • 其他硬件设备
    • 面包板跳线 一盒
    • 面包板 一块
    • LED发光二极管 六个
    • 220欧姆电阻 六个
    • USB数据连接线 一根

原理图

led的阴极接Microduino的GND,阳极接Microduino数据控制口A14、A15、A16、A17、A18、A19。

程序

char comdata[100];       //定义一个comdata数组,最大100个字符
int numdata[6] = {0};    //numdata是分拆之后的数字数组
int PWMPin[6] = {14,15,16,17,18,19};
int mark = 0;
void setup()
{ 
  for(int i = 0; i < 6; i++)    //定义引脚脚是输出模式
  {
    pinMode(PWMPin[i],PWM);
  }
}
 
void loop()
{ 
  int  datalength=0,j = 0; //datalength是接收数组的长度
                           //j是分拆之后数字数组的位置记数
  while (SerialUSB.available() > 0)        //不断循环检测串口缓存,一个个读入字符串,
  { 
    comdata[datalength++] =SerialUSB.read();      //读入之后将字符串接到comdata上面。    
    delay(2);     //延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
    mark = 1;     //标记串口读过数据,如果没有数据的话,直接不执行这个while了。
  }
  if(mark == 1)   //如果接收到数据则执行comdata分析操作,否则什么都不做。
  { 
    SerialUSB.println(comdata);     //显示刚才输入的字符串(可选语句)  
    SerialUSB.println(datalength);  //显示刚才输入的字符串长度(可选语句)    
/****************************下面是重点*****************************/  
    for(int i = 0; i <datalength; i++)   //以串口读取字符串长度循环,
    {
/****  逐个分析comdata[i]字符串的文字,如果碰到文字是分隔符(这里选择逗号分割)则将结果数组位置下移一位
*****  即比如11,22,33,55开始的11记到numdata[0];碰到逗号就j等于1了,
*****  再转换就转换到numdata[1];再碰到逗号就记到numdata[2];以此类推,直到字符串结束
*****/
      if(comdata[i] == ',')
      {
        j++;
      }
      else
      {
/****  如果没有逗号的话,就将读到的数字*10加上以前读入的数字,
*****  并且(comdata[i] - '0')就是将字符'0'的ASCII码转换成数字0(下面不再叙述此问题,直接视作数字0)。
*****  比如输入数字是12345,有5次没有碰到逗号的机会,就会执行5次此语句。
*****  因为左边的数字先获取到,并且numdata[0]等于0,
*****  所以第一次循环是numdata[0] = 0*10+1 = 1
*****  第二次numdata[0]等于1,循环是numdata[0] = 1*10+2 = 12
*****  第三次是numdata[0]等于12,循环是numdata[0] = 12*10+3 = 123
*****  第四次是numdata[0]等于123,循环是numdata[0] = 123*10+4 = 1234
*****  如此类推,字符串将被变成数字0。
*****/
        numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
      }
    }
/*   comdata的字符串已经全部转换到numdata了,清空comdata以便下一次使用,
     如果不请空的话,本次结果极有可能干扰下一次。*/
    for(int i=0;i<datalength;i++)
    {
      comdata[i]=0;
    }
    for(int i = 0; i < 6; i++)  //循环输出numdata的内容,并且写到PWM引脚
    {
      SerialUSB.print("Pin ");
      SerialUSB.print(PWMPin[i]);
      SerialUSB.print(" = ");
      SerialUSB.println(numdata[i]);
      pwmWrite(PWMPin[i], numdata[i]);
      numdata[i] = 0;
    }     
    mark = 0;             //输出之后必须将读到数据的mark置0,不置0下次循环就不能使用了。
  }
}

程序说明:

  • void pwmWrite(uint8 pin, uint16 duty_cycle)
  • 参数:pin为引脚编号。 duty_cycle为控制占空比的参数(0~65 535)。
  • 在使用pwmWrite()前必须先将引脚定义为“PWM”或是“PWM_OPENDRAIN”,只有0,1,4,11,12,14(A0),15(A1),16(A2),17(A3),18(SDA),19(SCL),20(A6),21(A7)引脚具有PWM输出功能。
  • 由于STM32处理器的PWM分辨率更高,所以duty_cycle是用16位数表示,范围为0~65535,分别表示0%~100%,而Microduino Core中PWM分辨率为256位,用0~255来表示0%~100%。

调试

结果

在串口数据输入6组用逗号隔开的数据可打印出6个PWM端口出对应PWM值

视频