本帖最后由 1208 于 2018-12-11 20:55 编辑
1)本程序最大的亮点就是用了软件复位(中断复位)
50s可以实现一个reset软件复位功能
可以减少按键硬件复位
这一段是分配STM32的中断向量表。从DCD后面表达式的名称可以看出第一个字存储单元
分配给了栈顶,其值为__initial_sp。第二个字分配给了复位地址,其值为Reset_Handler
((void(*)())( *(volatile unsigned long *)0x08000004) )(); //软件复位(中断复位)
为什么是0x08000004,因为初始地址是0x8000 0000,复位地址0x0000 0004
2)第二个亮点:发送058到串口,就可以点亮LED灯,并有8297数据输出
发送058,点灯问题不大
最主要是相应的输出8297数据,这个要怎么做,思前想后
通过数组的形式,在发送函数将数据发送出去
因为串口的发送和接收数据是ASCII(二进制),
需要通过加壳和去壳,来将数据转换
谨记:串口发送数据,要加壳;接收来的数据,要去壳
void send_tep()
{
int r=0;
u8 data[5];
data[0]=8+'0';
data[1]=0x02+'0'; //串口发送数据,要加壳
data[2]=0x09+'0'; //接收来的数据,要去壳
data[3]=0x07+'0';
USART_SendData(USART1,'\r');while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
for(r=0;r<4;r++)
{
USART_SendData(USART1,data[r]);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
}
3)软件复位直接用会出现乱码现象
需要在软件复位函数前面加一个延时
delay_ms(10);
((void(*)())( *(volatile unsigned long *)0x08000004) )(); //软件复位
4)long是32位整型,unsigned指无符号数,左边的*表示取内容
volatile表示易变的,告诉编译器不要优化,这个地址的内容不一定是在程序中改变的。
volatile unsigned long *表示将后面跟的内容转化成一个指针,并且是指向一个易变的无符号整数。
左边再加个*,表示取该指针指向地址的内容。
总的意思是取那个内存单元(内存地址0x08000004)里存的数,并将这个数转化为无符号整数
对指针变量引用,就能操作指针所指向的地址的内容了 *(volatile unsigned CHAR *)0x08000004 首先*(volatile unsigned long *)0x08000004的意思是把地址0x08000004强制
转换成volatile unsigned long类型的指针,暂记为p,
那么((void(*)())( *p()))就是强制转换成函数指针
[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
//ALIENTEK 探索者STM32F407开发板 实验4
//串口通信实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK
void send_tep();
int main(void)
{
u8 t;
u8 len;
u16 times=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //延时初始化
uart_init(115200); //串口初始化波特率为115200
LED_Init(); //初始化与LED连接的硬件接口
delay_ms(2000);
printf("reset");
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送的消息为:");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART_RX_BUF[t]); //向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
if(USART_RX_BUF[0]=='0'&&USART_RX_BUF[1]=='5'&&USART_RX_BUF[2]=='8')
{
printf("\r\nLED1亮\r\n");
LED1=0;
send_tep();
}
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nALIENTEK 探索者STM32F407开发板 串口实验\r\n");
printf("正点原子@ALIENTEK\r\n\r\n\r\n");
((void(*)())( *(volatile unsigned long *)0x08000004) )(); //软件复位
}
if(times%200==0)printf("请输入数据,以回车键结束\r\n");
if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}
void send_tep()
{
int r=0;
u8 data[5];
data[0]=8+'0';
data[1]=0x02+'0'; //串口发送数据,要加壳
data[2]=0x09+'0'; //接收来的数据,要去壳
data[3]=0x07+'0';
USART_SendData(USART1,'\r');while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
for(r=0;r<4;r++)
{
USART_SendData(USART1,data[r]);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
}
[/mw_shl_code]
|