|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 249018563 于 2017-7-14 16:35 编辑
1、安装编程环境 keil5 网盘地址:http://pan.baidu.com/s/1miRyj3a
2、坚持用到什么学什么的实用主义原则,绝不多学一点点 东拼西凑能实现我要的功能就好
3、第一章 学习STM32
(以前上学只让用飞思卡尔的芯片(MC92s12)) ,从头学吧,还能跟大家交流一下,虽然感觉帖子发错地方了。。。
第一课:点亮LED.
文件1:test.c
----------------------------------------------------------------------------------------------------------------------
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
/*****************************************************
File:LED应用
Author: Version:1.0 Data:2016/09/08
Description: LED闪烁
**********************************************************/
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置 外部8m晶振 <----就这个地方其实是是为了得到下边delay_init(72) 72 这个参数 72= 8*9
delay_init(72); //延时初始化 9倍频到72m
LED_Init(); //初始化与LED连接的硬件接口 pc13推挽输出
while(1)
{
LED = 1; // pc13口
delay_ms(500); //延时500毫秒
LED = 0;
delay_ms(500); //延时500毫秒
}
}
----------------------------------------------------------------------------------------------------------------------------
文件2:sys.c
-----------------------------------------------------------------------------------------------------------------------------
#include "sys.h"
//pll:选择的倍频数,从2开始,最大值为16
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;
MYRCC_DeInit(); //复位并配置向量表
RCC->CR|=0x00010000; //外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2; //抵消2个单位(因为是从2开始的,设置0就是2)
RCC->CFGR|=PLL<<18; //设置PLL值 2~16
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x32; //FLASH 2个延时周期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟
while(temp!=0x02) //等待PLL作为系统时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
-----------------------------------------------------------------------------------------------------------------------------
文件3:delay.c
---------------------------------------------------------------------------------------------------------------------------
void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
u32 reload;
#endif
SysTick->CTRL&=~(1<<2); //SYSTICK使用外部时钟源
fac_us=SYSCLK/8; //不论是否使用OS,fac_us都需要使用
#if SYSTEM_SUPPORT_OS //如果需要支持OS.
reload=SYSCLK/8; //每秒钟的计数次数 单位为K
reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间
//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位
SysTick->CTRL|=1<<1; //开启SYSTICK中断
SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
SysTick->CTRL|=1<<0; //开启SYSTICK
#else
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
#endif
}
void delay_ms(u16 nms) //毫秒延时
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
----------------------------------------------------------------------------------------------
文件4:led.c
----------------------------------------------------------------------------------------------------------
#include "led.h"
/*********************************************************
Copyright (C), 2016-2026, YFRobot.
www.yfrobot.com
File:LED驱动代码
Author:pinggai Version:1.0 Data:2016/09/08
Description: Balance-STM32 V2.0 LED驱动代码
Others: 使用端口 PC13
使用硬件资源 PC13
**********************************************************/
/******************************************************
Function: void LED_Init(void)
Description:LED IO初始化,设置PC13为输出端口
******************************************************/
void LED_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTC时钟(|= 可以防止操作其他位)
//APB2负责AD,I/O,串口1,高级TIM
//APB1负责DA,串口345,普通TIM,USB,IIC,CAN
GPIOC->CRH&=0XFF0FFFFF; //高8位 8-15口 ,0为13口,13口清空 ,不影响其他口
GPIOC->CRH|=0X00300000; //PC.13推挽输出 ,0x4模拟输入、0x3推挽输出(00 11,00指推挽输出,11指输出模式 50mhz)
//0x8 上拉或下拉输入,0xb复用输出
GPIOC->ODR|=1<<13; //PC.13输出高 odr端口输出数据寄存器
}
-----------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
好吧,其实注释已经很详细了,不过我估计这论坛大多数人不知道硬件c语言。其实都是c语言没什么区别的,我就自己督促自己学习吧。
这里给大家讲个小知识吧,我也复习一下,尽量给大家将明白,下面这两句话是让指定位变为0或1 而不改变其他位
GPIOC->CRH&=0XFF0FFFFF; //高8位 8-15口 ,0为13口,13口清空 ,不影响其他口
GPIOC->CRH|=0X00300000; //PC.13推挽输出 ,其他口与0或运算 不影响其他口
不知道大家看到这两句话没
我来简化一下
-------------------------------------------------------------------------------------------------------------------------------------------
知识点 &:与运算 0&0 ==0, 0&1==0 , 1&1=1
第一句简化为:a&=0//即a= a&0,这句话让a总为false
我们来分析一下 1、假如 a==0 现在让a和0做相与运算 即 a=0&0 a结果为0 即false
2、假如 a!=0(假如a为1不等于0) 现在让a和0做相与运算 即a=1&0 a结果也为0 即false
总结:a&=0 不论a以前为什么数,经过这句话运算后a被赋值为0
------------------------------------------------------------------------------------------------------------------
知识点: | 或运算 0|0==0 ,0|1==1, 1|1==1
第二句:a|=1 //经运算后a总为true 大家自己分析吧
---------------------------------------------------------------------------
对了还有个好玩的事,不知道大家看到没,死循环,这在硬件编程中很常见(之前那都是硬件寄存器配置,管用的只有下边这句话 ,换句话说那些都是前戏,让LED闪的其实就这点)
下边这段程序就是让LED 亮500毫秒,然后灭500毫秒,眼睛看到的效果就是LED在闪烁了,1秒闪烁一次
while(1)
{
LED = 1; // pc13口
delay_ms(500); //延时500毫秒
LED = 0;
delay_ms(500); //延时500毫秒
}
附:本课源码下载地址:http://pan.baidu.com/s/1eRWJTMa 我去打游戏了,码字好累 |
|