在某宝上购买的STM32F103C8T6最小核心板,通过网上的资料将其应用在Ardunio ID上。网上资料很多,最详细的https://blog.csdn.net/bobo184/article/details/84349184,但是他使用的不是某宝上的核心板。当你需要下载ST Microelectronics flash loader需要注册,然后到邮箱的邮件连接才能下载。不过有其他网友提到可以使用另外的烧写软件。在刷写时注意boot0与boot1的条线(两个都接高电平)。要不然总提示找不到芯片。完成后再将跳线都接低电平,下载安装STM32的库文件复制到Ardunio IDE的安装目录**\libraries**。就可以直接再Ardunio IDE中下载到STM32,除了资料少一些之外与Ardunio AVR之类的开发板没什么两样。
我这是公司之前定制的!不过某宝上也有这类模块。至于是315还是433其实并没多大关系。主要看遥控器的发射频率是否与接收器一致。我当时定制的也不清楚到底是哪个频率的了,所以只好把原来的解码芯片取掉了。然后将信号用引线接出来,输出引脚在SYN500的第10脚(DO)
在网上查了N多资料基本没怎么说如何使用中断的。最后只能使用笨办法。也许是我查找的方法不对吧。也或许英文资料应该是有的,只是我的水平不足而已。但也没关系了,最后还是解决了!在[WWW.ARDUNIO.CC]官网里的https://www.arduino.cc/reference/en/#functions 说明里找到了对应关于中断的解答。但是那也只是针对AVR的。没有对SMT32的说明。毕竟没有AVR和STM32的说明书。看来只好去测试了。先用一个红外线感应器来测试中断引脚。发现可以将某个引脚当中断使用,并不像AVR或51那样只能在特定的引脚才能使用中断。因为接收到的信号时单一的没有时钟同步。必须通过判断高低电平持续时间来决定传输的是0还是1。但是Ardunio只有pulseIn(pin, value, timeout)或pulseIn(pin, value)它的功能是需要一直等待设定的高低电平后返回持续时间。这个看起来挺合适的。但是它反应好慢,导致我在这个过程中耽误了好长的时间(一天),之后参考了RCLSwitch库和IRremote库,总算能够读取到对应持续时间的高低电平了。
#include //freeRTOS是嵌入式实时操作系
#include
#define BOARD_LED_PIN PC13 //定义板载LED(呼吸灯,运行中信号)为数字引脚2
#define SensorINPUT PB12 //定义感应器开关信号为数字引脚25
#define RC_Switch_INPUT PB13 //定义遥控接收信号为数字引脚26
#define StepMotorer_Dir PB14 //定义步进马达方向为数字引脚27
#define StepMotorer_En PB15 //定义步进马达使能开关为数字引脚28
#define StepMotorer_Step PA8 //定义步进马达步数频率为数字引脚29
#define Speeker_Out PB6 //蜂鸣器信号输出42
#define Stop 0 //定义停止状态为0
#define Run 1 //定义运行状态为1
#define CCW 0 //定义正转状态为0
#define CW 1 //定义反转状态为1
char SPEEK_MODE=0; //蜂鸣器鸣叫模式:0:停止 1:嘀一声 2:嘀嘀两声 3:一长一短间隔1秒重复3次 4:低鸣一声
unsigned long Rc_Start_5MS_MinTime = 4800;
unsigned long Rc_Start_5MS_MaxTime = 5500;
unsigned long Rc_Start_600us_MinTime = 530;
unsigned long Rc_Start_600us_MaxTime = 750;
unsigned long Rc_Data_600us = 500;
unsigned long Rc_Data_200us = 240;
#define RC_GROUP_LEN 8 //8帧数据
#define RC_DATA_LEN 8 //八字节
#define RC_BIT_LEN 8 //八位
volatile unsigned char Rf_buf[RC_GROUP_LEN][RC_DATA_LEN + 1], INDEX_GROUP = 0, INDEX_BUFFER = 0;
unsigned long Rc_Signal_Time = 0;
unsigned long Elapsed_Time = 0;
char Rc_Signal_Pin_Level = LOW;
bool WeillRead[2] = {false};
unsigned long High_Level_Time = 0; //RC_Switch数据段的高低电平时间
unsigned long Low_Level_Time = 0; //RC_Switch数据段的高低电平时间
char Input_i = 0; //输入信号电平变化数组索引
char Do_Input_i = 0; //在任务中处理输入信号电平变化数组索引
unsigned char RC_BIT = 0;
uint16 AddressWrite = 0x10; //分配遥控器ID保持到EEPROM的地址
char Old_RC_CMD=0,Public_Key_Cmd=0; //让其他任务处理的按键值,当其他任务处理后可以将清空
char Run_Stop = Stop;
char CCW_CW = CCW;
unsigned long AlowyTime = 0;
unsigned long End_Time = 0;
bool RC_Data_Frame_Status = false; //接收到数据帧是否结束标记
/////FreeRTOS 任务函数/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void vLEDFlashTask(void *pvParameters)
{
//
// Flash led every 200 ms.
for (;;)
{
if (AlowyTime > 2000)
{
digitalWrite(BOARD_LED_PIN, LOW); // Turn LED off.
Run_Stop = Stop;
CCW_CW = CW;
} else
{
if (digitalRead(SensorINPUT) == HIGH)
{
if (Run_Stop == Stop)
{
digitalWrite(BOARD_LED_PIN, HIGH); // Turn LED on.
vTaskDelay((1000 * configTICK_RATE_HZ) / 1000L);// Sleep for 50 milliseconds.
digitalWrite(BOARD_LED_PIN, LOW); // Turn LED off.
vTaskDelay((1000 * configTICK_RATE_HZ) / 1000L); // Sleep for 150 milliseconds.
} else
{
if (CCW_CW == CW)
{
digitalWrite(BOARD_LED_PIN, HIGH); // Turn LED on.
vTaskDelay((50 * configTICK_RATE_HZ) / 1000L);// Sleep for 50 milliseconds.
digitalWrite(BOARD_LED_PIN, LOW); // Turn LED off.
vTaskDelay((50 * configTICK_RATE_HZ) / 1000L); // Sleep for 150 milliseconds.
} else
{
digitalWrite(BOARD_LED_PIN, HIGH); // Turn LED on.
vTaskDelay((200 * configTICK_RATE_HZ) / 1000L);// Sleep for 50 milliseconds.
digitalWrite(BOARD_LED_PIN, LOW); // Turn LED off.
vTaskDelay((200 * configTICK_RATE_HZ) / 1000L); // Sleep for 150 milliseconds.
}
}
}
}
}
}
void SensorInter() { //感应器开关信号中断函数SensorInter()
unsigned long Stat_T = 0;
Stat_T = millis(); //micros();
if (digitalRead(SensorINPUT) == HIGH)
{
AlowyTime = Stat_T - End_Time;
//Serial.println(AlowyTime);
Run_Stop = !Run_Stop;
if (Run_Stop == Stop) CCW_CW = !CCW_CW;
}
End_Time = Stat_T;
}
uint16 RC_Write_ID(char ID0,char ID1)
{
uint16 DataWrite=ID0;
DataWrite<<=8;
DataWrite+=ID1;
Serial.print("W_ID:");Serial.print(ID0,HEX);Serial.print(",");Serial.println(ID1,HEX);
uint16 Status = EEPROM.write(AddressWrite, DataWrite);
return(Status);
}
bool RC_Cmp_ID(char ID0,char ID1) //比较遥控器的ID号,查看是否与本机匹配
{
uint16 EepRom_Data,ID=0;
uint16 Status = EEPROM.read(AddressWrite, &EepRom_Data);
ID=ID0;
ID<<=8;
ID+=ID1;
if(EepRom_Data==0xFFFF || EepRom_Data==0)
{
//Serial.println("Free ID");
return(true);
}
if(ID==EepRom_Data)return(true);
else return(false);
}
////315/433MHZ 自定义信号协议//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
起始头5毫秒高电平600微秒低电平 1(600微秒高电平200微秒低电平) 0(200微秒高电平600微秒低电平)
______________________ ____________ _________ _____
| | 5000US | |600US | |200US | | |
S 0 1 600US 2 3 200US 4 5 600US 6 |
|____| |__________| |_______| |__________| |___
*/
void RC_Switch_Inter() //遥控接收信号中断函数RC_Switch_Inter()
{
unsigned char ei,crc,RC_CMD;
unsigned long Now_Time = micros();
Rc_Signal_Pin_Level = digitalRead(RC_Switch_INPUT);
Elapsed_Time = Now_Time - Rc_Signal_Time;
Rc_Signal_Time = Now_Time;
if (Elapsed_Time > 6000) Elapsed_Time = 6000;
//判断高低电平信号持续时间
if (Rc_Signal_Pin_Level == LOW) //获得时序:1,3,5 下降沿,其实为高电平的持续时间,此时获得的信号引脚是低电平
{
High_Level_Time = Elapsed_Time; //上一次到现在的时间
}
else {//Rc_Signal_Pin_Level==HIGH//获得时序:1,4,6 上升沿,其实为低电平的持续时间,此时获得的信号引脚是高电平
Low_Level_Time = Elapsed_Time;
}//上一次到现在的时间
//检测信号起始帧
if (!WeillRead[1])
{
if (Rc_Signal_Pin_Level == HIGH && High_Level_Time <= Rc_Start_5MS_MaxTime && High_Level_Time >= Rc_Start_5MS_MinTime)
{
WeillRead[0] = true;
}
if (WeillRead[0] && Rc_Signal_Pin_Level == LOW)
{ if (Low_Level_Time <= Rc_Start_600us_MaxTime && Low_Level_Time >= Rc_Start_600us_MinTime)
{
WeillRead[1] = true;
RC_BIT = 0;
//Serial.println("^_^");
} else {
WeillRead[0] = false;
}
}
} else
{
//解析数据
digitalWrite(BOARD_LED_PIN, Rc_Signal_Pin_Level);
if (WeillRead[1] && Rc_Signal_Pin_Level == HIGH) //起始帧已经准备好,开始检测数据段和解析数据,并且信号引脚需要为高电平
{ //引脚为高电平的时候,其实已经表示获得了分别高低的各一次的信号,程序是在2,3或4,5之间做处理
Rf_buf[INDEX_GROUP][INDEX_BUFFER] <<= 1;
if (High_Level_Time >= Rc_Data_600us) Rf_buf[INDEX_GROUP][INDEX_BUFFER] += 1; //如果高电平持续时间大于数据帧定义的600us则表示为1 否则表示为0
else Rf_buf[INDEX_GROUP][INDEX_BUFFER] += 0;
RC_BIT++;
if (RC_BIT >= RC_BIT_LEN)
{
RC_BIT = 0;
//Serial.println(Rf_buf[INDEX_GROUP][INDEX_BUFFER]);
INDEX_BUFFER++; //下一字节
if (INDEX_BUFFER >= RC_DATA_LEN)
{ //数据接收结束准备下一帧的接收,清楚起始帧完成标记
INDEX_BUFFER = 0;
WeillRead[0] = false;
WeillRead[1] = false;
//校验数据是否接收正确
crc=0;
for(ei=1;ei<RC_DATA_LEN-1;ei++)//计算校验码
{
crc+=Rf_buf[INDEX_GROUP][ei];
}
if(crc==Rf_buf[INDEX_GROUP][ei] && 0x3A==Rf_buf[INDEX_GROUP][0])//匹配校验码
{
Rf_buf[INDEX_GROUP][ei+1]=1;
RC_CMD=Rf_buf[INDEX_GROUP][6];
if(RC_CMD!=36 && Old_RC_CMD != RC_CMD) //指令36表示按键松开
{
Old_RC_CMD = RC_CMD;
if(RC_Cmp_ID(Rf_buf[INDEX_GROUP][2],Rf_buf[INDEX_GROUP][3])) //比较遥控ID是否与本机匹配
{
SPEEK_MODE=1;
Public_Key_Cmd=RC_CMD; //返回共有按键值,让其他任务进行判断按键处理
Serial.print("Key:");Serial.println(RC_CMD);
}else{
SPEEK_MODE=4; //遥控器与本机不匹配,但收到信号(低鸣一声)
//Serial.print("IDErr:");Serial.println(RC_CMD);
}
}else
{ //按键松开处理
Old_RC_CMD=0;
}
if(RC_CMD==0x55)//配对遥控器,将遥控器的ID写入本机
{
RC_Write_ID(Rf_buf[INDEX_GROUP][2],Rf_buf[INDEX_GROUP][3]);
SPEEK_MODE=2; //嘀嘀两声
}
}
else{ //如果当前接收帧校验不对,表示接收不正确
INDEX_GROUP++;
RC_BIT = 0;
INDEX_BUFFER = 0;
if(INDEX_GROUP>RC_GROUP_LEN-1)INDEX_GROUP=0;
}
}
}
}
}
}
void setup() {
pinMode(BOARD_LED_PIN, OUTPUT);
pinMode(Speeker_Out, OUTPUT);
Serial.begin(115200);
uint16 Status = EEPROM.init();
attachInterrupt(digitalPinToInterrupt(SensorINPUT), SensorInter, CHANGE); //RISING); //创建中断
attachInterrupt(digitalPinToInterrupt(RC_Switch_INPUT), RC_Switch_Inter, CHANGE); //FALLING);
//创建线程
xTaskCreate(vLEDFlashTask,
"Task1",
configMINIMAL_STACK_SIZE,
NULL,
tskIDLE_PRIORITY + 2,
NULL);
vTaskStartScheduler();
}
void loop() {
}
一点心得和结晶,希望对各位网友能够有帮助吧!
相应的连接:CSDN 网友的 Arduino - 315/433MHz RF无线收发模块
CSDN 网友的 STM32F103C8T6在Arduino IDE里编程
使用Arduino解码并发送433MHz RF无线射频信号