本帖最后由 幻生幻灭 于 2015-6-19 08:16 编辑
之前做过一个方波发生器,参考下
- // Set CS10&CS11 bit for 64 prescaler
- // OCR1A = 255;
- //Pe = 2, pu = 1 cycle about 2 ms freq = 490Hz
- //Pe = 4, pu = 2 cycle about 4 ms freq = 247Hz
- //Pe = 6, pu = 3 cycle about 6 ms freq = 165Hz
- //Pe = 7, pu = 4 cycle about 7 ms freq = 140Hz
- //Pe = 8, pu = 4 cycle about 8 ms freq = 125Hz
- // OCR1A = 30;
- //Pe = 2, pu = 1 cycle about 0.1 ms freq = 4.03kHz
- //Pe = 4, pu = 2 cycle about 0.5 ms freq = 2.00kHz
- //Pe = 6, pu = 3 cycle about 0.8 ms freq = 1.35kHz
- //Pe = 8, pu = 4 cycle about 1 ms freq = 1.00kHz
- // OCR1A = 25;
- //Pe = 2, pu = 1 cycle about 0.2 ms freq = 4.83kHz
- //Pe = 10, pu = 5 cycle about 1 ms freq = 960Hz
- //Pe = 23, pu = 11 cycle about 2.2 ms freq = 420Hz
- //Pe = 40, pu = 20 cycle about 4 ms freq = 244Hz(****)
- //Pe = 50, pu = 25 cycle about 5.2 ms freq = 193Hz
- //Pe = 100, pu = 50 cycle about 10 ms freq = 100Hz
- //Pe = 1000, pu = 500 cycle about 100 ms freq = 9.7Hz
- //Pe = 2000, pu = 1000 cycle about 200 ms freq = 5Hz
- //Pe = 5000, pu = 2500 cycle about 510 ms freq = 1.9Hz(****)
- //Hardware connection
- //R10Kx2 + 1.5K
- //R20K(电位器) +1.5K
- //Measure Range: 4.651V(0 - 950)
- //Period Range: 40 - 5000
- //Calculation: Period = 40 + A0*5(Range: 40 - 4790)
- //Calculation: PulseWidth = int((A1/950)*period)
- //Hardware Define
- int pinFreq = A2;
- int pinPulseWidth = A1;
- int pinFreqR = A3;
- int pinPulseWidthR = A0;
- int pinLed = 3;
- int pinPWM = 4;
- int pinKey = 5;
- int pinKeyV = 6;
- int pinKeyG = 7;
- int pinKeyVisu = 13;
- //variables for PW pot monitoring
- float pulseWidth;
- int pulseWidthScaled;
- int PWCurrent;
- byte PWTolerance = 2;//adjust this to increase/decrease stability of PW measurement
- //variables for freq pot monitoring
- int frequency;
- int freqCurrent;
- byte freqTolerance = 2;//adjust this to increase/decrease stability of frequency measurement
- unsigned int freqscaled;
- int t;
- int period;
- int testMode = 0; //Default is 0;
- int freqPreTest;
- int PWPreTest;
- //int cycleISR = 4; //unit us
- //定义一个comdata字符串变量,赋初值为空值
- String comdata = "";
- //numdata是分拆之后的数字数组
- int numdata[2] = {
- 0};
- int mark = 0;
- void setup() {
- Serial.begin(9600);
- //set port/pin mode
- pinMode(pinLed, OUTPUT);
- pinMode(pinPWM, OUTPUT);
- pinMode(pinKeyV, OUTPUT);
- pinMode(pinKeyG, OUTPUT);
- pinMode(pinKeyVisu, OUTPUT);
- pinMode(pinKey, INPUT);
- digitalWrite(pinKeyV, HIGH);
- digitalWrite(pinKeyG, LOW);
- digitalWrite(pinKeyVisu, LOW);
- //TIMER INTERRUPT SETUP
- cli();//disable interrupts
- //timer 1:
- TCCR1A = 0;// set entire TCCR1A register to 0
- TCCR1B = 0;// same for TCCR1B
- //set compare match register- 100khz to start
- OCR1A = 25; //period = 0.1ms
- //turn on CTC mode
- TCCR1B |= (1 << WGM12);
- // Set CS10&CS11 bit for 64 prescaler
- TCCR1B |= (1 << CS10) | (1 << CS11);
- // enable timer compare interrupt
- TIMSK1 |= (1 << OCIE1A);
- //initialize variables 200Hz
- t = 0;
- period = 48;
- pulseWidthScaled = 24;
- sei();//enable interrupts
- if(testMode == 1){
- Serial.println(" ");
- Serial.println("Test Mode Actived!");
- }
- }
- //Leo checked
- ISR(TIMER1_COMPA_vect){//timer 1 interrupt
- //increment t and reset each time it reaches period
- t += 1;
- if (t >= period){
- t = 0;
- }
- if (pulseWidthScaled <= t) {
- //PORTD = 0xff;
- digitalWrite(pinPWM, HIGH);
- digitalWrite(pinLed, HIGH);
- }
- else{
- //PORTD = 0x00;
- digitalWrite(pinPWM, LOW);
- digitalWrite(pinLed, LOW);
- }
- }
- //Leo checked
- void loop() {
- if(testMode == 1) SerialInput();
- checkFreq();
- checkPW();
- if(digitalRead(pinKey) == HIGH){
- digitalWrite(pinKeyVisu, HIGH);
- }
- else{
- digitalWrite(pinKeyVisu, LOW);
- }
- }
- //Leo checked
- void checkFreq() {
- if(digitalRead(pinKey) == HIGH){
- freqCurrent = analogRead(pinFreq);
- }
- else{
- freqCurrent = analogRead(pinFreqR);
- }
- if(testMode == 1) freqCurrent = freqPreTest;
- if (abs(freqCurrent-frequency)>freqTolerance){//if reading from pot exceeds tolerance
- frequency = freqCurrent;
- period = 40 + frequency*5; //Range: 40 - 4790
- }
- }
- //Leo checked
- void checkPW() {
- if(digitalRead(pinKey) == HIGH){
- PWCurrent = analogRead(pinPulseWidth);
- }
- else{
- PWCurrent = analogRead(pinPulseWidthR);
- }
- if(testMode == 1) PWCurrent = PWPreTest;
- if (abs(PWCurrent-pulseWidth)>PWTolerance){//if reading from pot exceeds tolerance
- pulseWidth = PWCurrent;//new pulse width, val between 0 and 1023
- if(digitalRead(pinKey) == HIGH){
- pulseWidthScaled = int((pulseWidth/930)*period);
- }
- else{
- pulseWidthScaled = int((pulseWidth/1023)*period);
- }
- }
- }
- //Leo checked
- void SerialInput(){
- //j是分拆之后数字数组的位置记数
- int j = 0;
- //不断循环检测串口缓存,一个个读入字符串,
- while (Serial.available() > 0)
- {
- //读入之后将字符串,串接到comdata上面。
- comdata += char(Serial.read());
- //延时一会,让串口缓存准备好下一个数字,不延时会导致数据丢失,
- delay(2);
- //标记串口读过数据,如果没有数据的话,直接不执行这个while了。
- mark = 1;
- }
- if(mark == 1) //如果接收到数据则执行comdata分析操作,否则什么都不做。
- {
- //显示刚才输入的字符串(可选语句)
- //Serial.println(comdata);
- //显示刚才输入的字符串长度(可选语句)
- //Serial.println(comdata.length());
- /*******************下面是重点*******************/
- //以串口读取字符串长度循环,
- for(int i = 0; i < comdata.length() ; 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以便下一次使用,
- //如果不请空的话,本次结果极有可能干扰下一次。
- comdata = String("");
- period = numdata[0];
- pulseWidthScaled = numdata[1];
- Serial.println("P----------------");
- if(digitalRead(pinKey) == HIGH){
- Serial.println("IN2 & IN3 is actived! ");
- }
- else{
- Serial.println("IN1 & IN4 is actived! ");
- }
- Serial.print("period: ");
- Serial.println(period);
- Serial.print("pulseWidthScaled: ");
- Serial.println(pulseWidthScaled);
- //循环输出numdata的内容,并且写到PWM引脚
- for(int i = 0; i < 2; i++)
- {
- numdata[i] = 0;
- }
- //输出之后必须将读到数据的mark置0,不置0下次循环就不能使用了。
- mark = 0;
- }
- }
复制代码
Ref:
http://www.instructables.com/id/ ... or-Shield/?ALLSTEPS
Arduino学习笔记A6(补充) - 在串口读取多个字符串,并且转换为数字数组
http://www.geek-workshop.com/thread-260-1-1.html
|