鱼C论坛

 找回密码
 立即注册
查看: 3015|回复: 3

[见证历程] 圆梦那年3(c语言)---废话少说上干货

[复制链接]
发表于 2017-7-4 22:06:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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  我去打游戏了,码字好累
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-7-5 09:01:07 | 显示全部楼层
还在学基础,顶一下~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-12 10:32:08 | 显示全部楼层
表示能看懂。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-23 17:51:42 | 显示全部楼层
太厉害楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 17:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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