OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3747|回复: 6

[探索者F407] 分享:探索者串口点灯和数据发送+软复位

[复制链接]

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-10-1 10:20:23 | 显示全部楼层 |阅读模式
本帖最后由 1208 于 2018-12-11 20:55 编辑

1)本程序最大的亮点就是用了软件复位(中断复位)
50s可以实现一个reset软件复位功能
可以减少按键硬件复位
向量.JPG
这一段是分配STM32的中断向量表。从DCD后面表达式的名称可以看出第一个字存储单元
分配给了栈顶,其值为__initial_sp。第二个字分配给了复位地址,其值为Reset_Handler
((void(*)())( *(volatile unsigned long *)0x08000004) )(); //软件复位(中断复位)
为什么是0x08000004,因为初始地址是0x8000 0000,复位地址0x0000 0004
初始地址.JPG 中断复位.JPG
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]

探索者实验4 串口实验+软复位.zip

3.96 MB, 下载次数: 126

业精于勤荒于嬉;行成于思毁于随!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
 楼主| 发表于 2018-10-1 10:21:41 | 显示全部楼层
这个reset会出现乱码,有什么好的解决办法
业精于勤荒于嬉;行成于思毁于随!
回复 支持 反对

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
 楼主| 发表于 2018-12-11 17:08:35 | 显示全部楼层
原来加个延时就可以了
业精于勤荒于嬉;行成于思毁于随!
回复 支持 反对

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-11 17:18:11 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-11 17:19:18 | 显示全部楼层
1208 发表于 2018-12-11 17:08
原来加个延时就可以了

加哪里的?
Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复 支持 反对

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
 楼主| 发表于 2018-12-11 17:47:57 | 显示全部楼层

加在软件复位语句前面就行
业精于勤荒于嬉;行成于思毁于随!
回复 支持 反对

使用道具 举报

13

主题

633

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1331
金钱
1331
注册时间
2016-8-1
在线时间
229 小时
发表于 2018-12-11 18:07:21 | 显示全部楼层
关中断代替延时 试试
所以,最好在发出复位请求前,先把FAULTMASK置位。需要加上这句:__set_FAULTMASK(1);意思是关闭所有中断的意思,目的是在执行NVIC_SystemReset()复位函数过程中不被中断所打断。两个函数执行后系统复位重新执行代码,包括之前所配置好的外设寄存器也都回到复位状态。如下:
__set_FAULTMASK(1);//关闭所有中断
NVIC_SystemReset();//复位函数
注意2:上面两个函数在core_cm3.h里面都有定义如下:
static __INLINE void NVIC_SystemReset(void)
{
  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                 SCB_AIRCR_SYSRESETREQ_Msk);                  
  __DSB();                                                                  
  while(1);                                                   
}

Loto虚拟示波器 官方qq群: 706769836 https://shop296209296.taobao.com/shop/view_shop.htm?tracelog=t
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 22:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表