
好久没在首页发布消息了,因为硬件平台的缘故,提及下。
缘由:RT-Thread本身支持多个平台,平台的多样化是开源社区的特性。但因为平台的多样化也导致了:当用户遇到问题时问题呈现完全发散状态。有的时候问题反馈上来我们自己都摸不着头脑(更别说有时用户叙述表达不清的情况)。
所以我们一直想着是否能够把这些收敛一下。基于我们原来STM32Radio的经验:STM32Radio硬件,二十来个涉及到方方面面的配套例程,以及一个大例程,使得大家能够比较好的了解RT-Thread、学习RT-Thread。基于这些,我们去年年底以来一直在考虑新的硬件平台:提供给大家一个入门级的硬件平台,使得大家入门更为方便,即使遇到了问题也可以基于同一套硬件平台上大家一起来交流、讨论、解决问题。这些硬件平台包括:ART和RealTouch。
ART - 一套与国外Arduino接口兼容的,面向初学者、DIY用户的核心板。目前的芯片核心是100管脚的STM32F407,硬件由Arda同学设计。它可以通过扩展的方式支持各类外设,从各类传感器(温度、湿度、压力、烟雾等等),到SPI接口的各类EMAC、WIFI。当然还有CAN,USB Device/Host。USB Host能够直接连接Android手机。软件上,除了通常的RT-Thread系统,还会启用很多RT-Thread上的新特性,例如新文件系统,POSIX接口。还有很神奇的Arduino程序环境,既把Arduino的简洁融合进来,也把RT-Thread的多任务性发挥出来(这得益于RT-Thread的应用模块功能)。
RealTouch - 一套面向人机交互、触摸屏控制的大设备。“大”设备有多大:7寸TFT屏幕,甚至有完整的外壳(当然DIY特性是必备的,外壳后面有UART接口、SWD调试接口)。类似以前的STM32Radio,它还包含音频接口。既然音频有了,后续是否能够有视频呢?很期待!芯片上,依然是ARM Cortex-M4。基本上,RealTouch能够基于ARM Cortex-M4芯片了解到RT-Thread的每一个角落。
建议入门者,不需要GUI特性的可以多关注ART;公司企业产品项目,可以关注RealTouch。目前这两个硬件平台都慢慢进入预定状态,同样针对于好学的学生(申请条件后续更新),我们也会免费借出一些硬件平台,RT-Thread Developer也可以免费申请这些硬件平台(后续情况请关注我们的微博或论坛)。

参考网友——正点原子之寄存器操作STM32F103ZE
寄存器操作:实验1 LED流水灯
STM32 IO简介 作为所有开发板的经典入门实验,莫过于跑马灯了。 该实验的关键在于如何控制STM32的IO口输出。了解了STM32的IO口如何输出的,就可以实现跑马灯了。通过这一节的学习,你将初步掌握STM32基本IO口的使用,而这是迈向STM32的第一步。 STM32的IO口可以由软件配置成8种模式: 1、输入浮空 2、输入上拉 3、输入下拉 4、模拟输入 5、开漏输出 6、推挽输出 7、推挽式复用功能 8、开漏复用功能 每个IO口可以自由编程,单IO口寄存器必须要按32位字被访问。STM32的很多IO口都是5V兼容的,这些IO口在与5V电平的外设连接的时候很有优势,具体哪些IO口是5V兼容的,可以从该芯片的数据手册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。 STM32的每个IO端口都有7个寄存器来控制。他们分别是:配置模式的2个32位的端口配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR;1个32位的锁存寄存器LCKR;这里我们仅介绍常用 的几个寄存器,我们常用的IO端口寄存器只有4个:CRL、CRH、IDR、ODR。 CRL和CRH控制着每个IO口的模式及输出速率。
该寄存器的复位值为0X4444 4444,从上图可以看到,复位值其实就是配置端口为浮空输入模式。从上图还可以得出:STM32的CRL控制着每个IO端口(A~G)的低8位的模式。每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。这里我们可以记住几个常用的配置,比如0X4表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。 CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。这里我们对CRH就不做详细介绍了。
给个实例,比如我们要设置PE2,3,4,5位为推挽输出。
代码如下: GPIOE->CRL&=0XFF0000FF;
GPIOE->CRL|=0X00333300;//PE2,3,4,5推挽输出
GPIOE->ODR|=0X003C; //PE2,3,4,5输出高 通过这3句话的配置,我们就设置了PE2,3,4,5推挽输出。 ODR是一个端口输出数据寄存器,只用了低16位。
led.c文件部分内容:
//初始化PE2,3,4,5推挽输出.并使能PORTE时钟
//LED IO初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<6; //使能PORTE时钟
GPIOE->CRL&=0XFF0000FF;
GPIOE->CRL|=0X00333300;//PE2,3,4,5推挽输出
GPIOE->ODR|=0X003C; //PE2,3,4,5输出高
}
led.h文件部分内容:
//LED端口定义
#define LED0 PEout(2)// PE2
#define LED1 PEout(3)// PE3
#define LED2 PEout(4)// PE4
#define LED3 PEout(5)// PE5
void LED_Init(void);//初始化
主函数:
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED0=0;
LED1=1;
delay_ms(300);
LED0=1;
LED1=0;
delay_ms(300);
}
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验1 LED流水灯.rar

key.c文件:
//PA0.PC13.PF11 设置成输入
void KEY_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<4; //使能PORTC时钟
RCC->APB2ENR|=1<<7; //使能PORTF时钟
GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
GPIOA->CRL|=0X00000008;
GPIOC->CRH&=0XFF0FFFFF;//PC13设置成输入
GPIOC->CRH|=0X00800000;
GPIOF->CRH&=0XFFFF0FFF;//PF11设置成输入
GPIOF->CRH|=0X00008000;
GPIOC->ODR|=1<<13; //PC13上拉,PA0默认下拉
GPIOF->ODR|=1<<11; //PF11上拉
}
//按键处理函数
//返回按键值
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2!!
u8 KEY_Scan(void)
{
static u8 key_up=1;//按键按松开标志
if(key_up&&(KEY0==0||KEY1==0||KEY2==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)
{
return 1;
}
else if(KEY1==0)
{
return 2;
}
else if(KEY2==1)
{
return 3;
}
}else if(KEY0==1&&KEY1==1&&KEY2==0)key_up=1;
return 0;// 无按键按下
}
这段代码包含2 个函数,void KEY_Init(void)和u8 KEY_Scan(void),KEY_Init 是用来初始
化按键输入的IO 口的。实现PA0、PC13、PF11 的输入设置,这里和上一节的输出配置差不多,只是这里用来设置成的是输入而上一节是输出。
KEY_Scan 函数,则是用来扫描这3 个IO 口是否有按键按下。这个KEY_Scan 函数,扫描
某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的
好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。同时还有一点
要注意的就是,该函数的按键扫描是有优先级的,最优先的是KEY0,第二优先的是KEY1,
最后是KEY2(KEY2 对应WK_UP 按键)。该函数有返回值,如果有按键按下,则返回非0 值,如果没有或者按键不正确,则返回0。具体怎么实现请参考KEY_Scan 的代码。
key.h文件:
#define KEY0 PFin(11) //PF11 User_Button
#define KEY1 PCin(13) //PC13 Anti_Tamper
#define KEY2 PAin(0) //PA0 WK_UP
void KEY_Init(void);//IO初始化
u8 KEY_Scan(void); //按键扫描函数
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验2 按键输入.rar

主函数:
int main(void)
{
u8 t;
u8 len;
u16 times=0;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
if(USART_RX_STA&0x80)
{
len=USART_RX_STA&0x3f;//得到此次接收到的数据长度
printf("\n您发送的消息为:\n");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR&0X40)==0);//等待发送结束
}
printf("\n\n");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\nEEPW_ARM_DIY开发板 串口实验\n");
}
if(times%200==0)printf("请输入数据,以回车键结束\n");
if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验3 串口实验.rar

寄存器操作:实验4 外部中断实验
exit.c文件:
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10);//消抖
if(KEY2==1) //按键2
{
LED0=!LED0;
LED1=!LED1;
}
EXTI->PR=1<<0; //清除LINE0上的中断标志位
}
//外部中断15~10服务程序
void EXTI15_10_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0) //按键0
{
LED0=!LED0;
}else if(KEY1==0)//按键1
{
LED1=!LED1;
}
EXTI->PR=1<<11; //清除LINE11上的中断标志位
EXTI->PR=1<<13; //清除LINE13上的中断标志位
}
//外部中断初始化程序
//初始化PA0,PC13,PF11为中断输入.
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<4; //使能PORTC时钟
RCC->APB2ENR|=1<<7; //使能PORTF时钟
GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
GPIOA->CRL|=0X00000008;
GPIOC->CRH&=0XFF0FFFFF;//PC13设置成输入
GPIOC->CRH|=0X00800000;
GPIOF->CRH&=0XFFFF0FFF;//PF11设置成输入
GPIOF->CRH|=0X00008000;
GPIOC->ODR|=1<<13; //PC13上拉,PA0默认下拉
GPIOF->ODR|=1<<15; //PF11上拉
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
Ex_NVIC_Config(GPIO_C,13,FTIR);//下降沿触发
Ex_NVIC_Config(GPIO_F,11,FTIR);//下降沿触发
MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2
MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2
}
exit.h文件:
void EXTIX_Init(void);//IO初始化
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验4 外部中断实验.rar

//初始化独立看门狗
//prer:分频数:0~7(只有低3位有效!)
//分频因子=4*2^prer.但最大值只能是256!
//rlr:重装载寄存器值:低11位有效.
//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG->KR=0X5555;//使能对IWDG->PR和IWDG->RLR的写
IWDG->PR=prer; //设置分频系数
IWDG->RLR=rlr; //从加载寄存器 IWDG->RLR
IWDG->KR=0XAAAA;//reload
IWDG->KR=0XCCCC;//使能看门狗
}
//喂独立看门狗
void IWDG_Feed(void)
{
IWDG->KR=0XAAAA;//reload
}
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //按键初始化
delay_ms(300); //让人看得到灭
IWDG_Init(4,625); //与分频数为64,重载值为625,溢出时间为1s
LED0=0; //点亮LED0
while(1)
{
if(KEY_Scan()==3)IWDG_Feed();//如果WK_UP按下,则喂狗
delay_ms(10);
};
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验5 独立看门狗实验.rar

//保存WWDG计数器的设置值,默认为最大.
u8 WWDG_CNT=0x7f;
//初始化窗口看门狗
//tr :T[6:0],用于存储计数器的值
//wr :W[6:0],用于存储窗口值
//fprer:窗口看门狗的实际设置
//低2位有效.Fwwdg=PCLK1/4096/2^fprer.
void WWDG_Init(u8 tr,u8 wr,u8 fprer)
{
RCC->APB1ENR|=1<<11; //使能wwdg时钟
WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG->CFR|=fprer<<7; //PCLK1/4096再除2^fprer
WWDG->CFR|=1<<9; //使能提前唤醒中断
WWDG->CFR&=0XFF80;
WWDG->CFR|=wr; //设定窗口值
WWDG->CR|=WWDG_CNT|(1<<7); //开启看门狗,设置7位计数器
MY_NVIC_Init(2,3,WWDG_IRQChannel,2);//抢占2,子优先级3,组2
}
//重设置WWDG计数器的值
void WWDG_Set_Counter(u8 cnt)
{
WWDG->CR|=(cnt&0x7F);//重设置7位计数器
}
//窗口看门狗中断服务程序
void WWDG_IRQHandler(void)
{
u8 wr,tr;
wr=WWDG->CFR&0X7F;
tr=WWDG->CR&0X7F;
if(tr<wr)WWDG_Set_Counter(WWDG_CNT);//只有当计数器的值,小于窗口寄存器的值才能写CR!!
WWDG->SR=0X00;//清除提前唤醒中断标志位
LED1=!LED1;
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验6 窗口看门狗实验.rar

void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//溢出中断
{
LED1=!LED1;
}
TIM3->SR&=~(1<<0);//清除中断标志位
}
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void Timerx_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1;//TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms
TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟
//这两个东东要同时设置才可以使用中断
TIM3->DIER|=1<<0; //允许更新中断
TIM3->DIER|=1<<6; //允许触发中断
TIM3->CR1|=0x01; //使能定时器3
MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:实验7 定时器中断实验.rar

//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void PWM_Init(u16 arr,u16 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<1; //TIM3时钟使能
GPIOE->CRL&=0XFFFFF0FF;//PE2输出
GPIOE->CRL|=0X00000400;//浮空输入
GPIOA->CRL&=0X0FFFFFFF;//PA7输出
GPIOA->CRL|=0XB0000000;//复用功能输出
GPIOA->ODR|=1<<7;//PA7上拉
TIM3->ARR=arr;//设定计数器自动重装值
TIM3->PSC=psc;//预分频器不分频
TIM3->CCMR1|=7<<12; //CH2 PWM2模式
TIM3->CCMR1|=1<<11; //CH2预装载使能
TIM3->CCER|=1<<4; //OC2 输出使能
}
详情请登录网友——正点原子官方论坛http://www.openedv.com/forums/list.htm或下载《STM32不完全手册V2.0》
源代码:
实验8 PWM输出实验.rar
回复
有奖活动 | |
---|---|
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】电感选型错误导致的处理器连接不上被打赏50分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏10分 | |
【我踩过的那些坑】DRC使用位置错误导致的问题被打赏100分 | |
我踩过的那些坑之混合OTL功放与落地音箱被打赏50分 | |
汽车电子中巡航控制系统的使用被打赏10分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏100分 | |
分享汽车电子中巡航控制系统知识被打赏10分 | |
分享安全气囊系统的检修注意事项被打赏10分 | |
分享电子控制安全气囊计算机知识点被打赏10分 | |
【分享开发笔记,赚取电动螺丝刀】【OZONE】使用方法总结被打赏20分 |