久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5864|回復: 0
打印 上一主題 下一主題
收起左側

Stm32學習筆記—寄存器版本

[復制鏈接]
跳轉到指定樓層
樓主
ID:87663 發(fā)表于 2015-8-9 11:56 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

養(yǎng)成良好的編程能力很重要!!!否則還以后的生活和工作當中會吃很大的虧的!
一、在MDK中進行對stm32的學習中用寄存器進行學習只需要很簡單的操作,比起用庫函數(shù)大大降低了學習的難度。。。
1)首先將system文件夾中的delay、sys以及usart三個文件夾復制到工程文件夾中并添加進工程當中去,然后再把一個啟動文件復制到工程當中去并添加即可。
二、LED跑馬燈的學習:
1)編寫LED初始化函數(shù),這其中包括GPIOX時鐘的使能,然后就是對應LED的端口的設置,其中包括輸入輸出模式以及輸出的形式(是高電平還是低電平);
2)編寫完成之后就是調用LED初始化函數(shù)進行試驗。代碼如下:
void LED_Init(void)
{
        RCC->APB2ENR|=1<<3;    //使能PORTB時鐘                    
        RCC->APB2ENR|=1<<6;    //使能PORTE時鐘        
                    
        GPIOB->CRL&=0XFF0FFFFF; //輸出模式
        GPIOB->CRL|=0X00300000;//PB.5 推挽輸出            
    GPIOB->ODR|=1<<5;      //PB.5 輸出高
                                                                                          
        GPIOE->CRL&=0XFF0FFFFF;
        GPIOE->CRL|=0X00300000;//PE.5推挽輸出
        GPIOE->ODR|=1<<5;      //PE.5輸出高
}
3)stm32中的IO口初始化之后默認的形式是下拉的。下面是幾種常見的輸入形式,最好記住
三、用串口發(fā)送和接受數(shù)據(jù)
1)首先肯定是使能串口時鐘和串口所對應的io口時鐘,設置io口的輸入輸出模式,然后復位串口、停止復位,設置波特率和校檢位。至此串口已經(jīng)初始化完畢。串口的波特率是根據(jù)以下公式算的以下是初始化串口的函數(shù)
void uart_init(u32 pclk2,u32 bound)
{           
        float temp;
        u16 mantissa;
        u16 fraction;           
        temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
        mantissa=temp;                                 //得到整數(shù)部分
        fraction=(temp-mantissa)*16; //得到小數(shù)部分         
    mantissa<<=4;//將最后的一個16進制位移開再與小數(shù)位相加
        mantissa+=fraction;
        RCC->APB2ENR|=1<<2;   //使能PORTA口時鐘  
        RCC->APB2ENR|=1<<14;  //使能串口時鐘
        GPIOA->CRH&=0XFFFFF00F;//IO狀態(tài)設置
        GPIOA->CRH|=0X000008B0;//IO狀態(tài)設置
                  
        RCC->APB2RSTR|=1<<14;   //復位串口1
        RCC->APB2RSTR&=~(1<<14);//停止復位                     
        //波特率設置
         USART1->BRR=mantissa; // 波特率設置         
        USART1->CR1|=0X200C;  //1位起始,無校驗位.
#if EN_USART1_RX                  //如果使能了接收
        //使能接收中斷
        USART1->CR1|=1<<8;    //PE中斷使能
        USART1->CR1|=1<<5;    //接收緩沖區(qū)非空中斷使能                    
        MY_NVIC_Init(3,3,USART1_IRQn,2);//組2,最低優(yōu)先級
#endif
}
四、外部中斷事件
1)初始化IO口為輸入。
2)開啟IO口復用時鐘,設置IO口與中斷線的映射關系。APB2ENR寄存器
3)開啟與該IO口相對的線上事件,設置觸發(fā)事件的條件。EXTI->FTSR下降沿觸發(fā)發(fā)、EXTI->RTSR 上升沿觸
4)配置中斷分組(NVIC)并使能中斷。RCC_CIR寄存器
5)編寫中斷服務函數(shù)。
五、獨立看門狗事件(注意,在初始化時鐘或者是計數(shù)器的時候應該是最后才使能時鐘或者是計數(shù)器)
1)在鍵寄存器(IWDG_KR)中寫入0xCCCC,開始啟用獨立看門狗
2)IWDG_PR和IWDG_RLR寄存器具有寫保護功能。要修改這兩個寄存器的值,必須先向IWDG_KR寄存器中寫入0x5555。以不同的值寫入這個寄存器將會打亂操作順序,寄存器將重新被保護。重裝載操作(即寫入0xAAAA)也會啟動寫保護功能。
void IWDG_Init(u8 prer,u16 rlr)
{
        IWDG->KR=0X5555;//使能對IWDG->PR和IWDG->RLR的寫,因為KR寄存器有寫保護功能                                                                                                   
          IWDG->PR=prer;  //設置分頻系數(shù)   
          IWDG->RLR=rlr;  //從加載寄存器 IWDG->RLR  
        IWDG->KR=0XAAAA;//reload                                                                                          
          IWDG->KR=0XCCCC;//使能看門狗        
}
3)獨立看門狗計數(shù)器一旦開始后就要不斷地對其進行喂狗操作,否則當其被計數(shù)到零時就會引起系統(tǒng)復位。喂狗操作就是想KR寄存器中寫入0xAAAA,使其自動進行重載操作。
void IWDG_Feed(void)
{
        IWDG->KR=0XAAAA;//reload                                                                                          
}
六、窗口看門狗事件
1)首先使能窗口看門狗時鐘,在RCC->APB1ENR中的11位置1
2)控制寄存器的配置(WWDG->CR),這個寄存器只有低7位有效。第7位為看門狗使能位,[6:0]為看門狗計數(shù)器的值,當?shù)?位為0時就會引起系統(tǒng)復位。

3)看門狗配置寄存器(WWWDG_CFR),這個寄存器為低10位有效其中[6:0]位為窗口值;值得注意的是只有當計數(shù)器的值小于窗口值時并且大于0x40時才能重新寫入計數(shù)器的值,否則會引起系統(tǒng)復位。不管是提前還是延后都會引起系統(tǒng)復位。具體在stm32中文參考手冊的321頁
4)窗口看門狗的狀態(tài)寄存器WWDG_SR只有一位,但是起作用卻很重要。當該寄存器的0位置1時為提前喚醒中斷標志,即當控制寄存器的中的計數(shù)器的值從0x40轉變?yōu)?x3f時會引起中,可以利用這個中斷來進行喂狗。以下是初始化窗口看門狗的初始化函數(shù)
//初始化窗口看門狗         
//tr   :T[6:0],計數(shù)器值
//wr   :W[6:0],窗口值
//fprer:分頻系數(shù)(WDGTB),僅最低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&=0XFF80;      
        WWDG->CFR|=wr;                     //設定窗口值      
        WWDG->CR|=WWDG_CNT;         //設定計數(shù)器值
        WWDG->CR|=1<<7;                  //開啟看門狗      
        MY_NVIC_Init(2,3,WWDG_IRQn,2);//搶占2,子優(yōu)先級3,組2     
        WWDG->SR=0X00;                         //清除提前喚醒中斷標志位
        WWDG->CFR|=1<<9;        //使能提前喚醒中斷
}
中斷服務函數(shù)為
void WWDG_IRQHandler(void)
{      
        WWDG_Set_Counter(WWDG_CNT);//重設窗口看門狗的值!         
        WWDG->SR=0X00;//清除提前喚醒中斷標志位
        LED1=!LED1;
        BEEP=0;
}
七、通用計數(shù)器的使用
通用計數(shù)器的初始化步驟如下
1)使能計數(shù)器的時鐘RCC->APB1ENRd的第1位
2)設置自動加載寄存器的值,即為計數(shù)值
3)設置預分頻器的分頻值
4)設置計數(shù)器的計數(shù)防方向,是向下還是向上計數(shù),默認狀態(tài)下是向上計數(shù)的
5)使能計數(shù)器
6)設置計數(shù)器的中斷方式并編寫中斷服務函數(shù)(當計數(shù)器溢出時會響應一個中斷,中斷使能寄存器的0位會置1,但是前提是在DMA/中斷使能寄存器中將更新事件的中斷使能位置1)
//通用定時器3中斷初始化
//這里時鐘選擇為APB1的2倍,而APB1為36M
//arr:自動重裝值。
//psc:時鐘預分頻數(shù)
//這里使用的是定時器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
        RCC->APB1ENR|=1<<1;        //TIM3時鐘使能   
         TIM3->ARR=arr;          //設定計數(shù)器自動重裝值//剛好1ms   
        TIM3->PSC=psc;          //預分頻器7200,得到10Khz的計數(shù)時鐘                  
        TIM3->DIER|=1<<0;         //允許更新中斷
        TIM3->CR1|= 1<<4;        //設置計數(shù)器是向下計數(shù),默認狀態(tài)下是向上計數(shù)的            
        TIM3->CR1|=0x01;    //使能定時器3
MY_NVIC_Init(1,3,TIM3_IRQn,2);//搶占1,子優(yōu)先級3,組2                                                                        
}
//定時器3中斷服務程序         
void TIM3_IRQHandler(void)
{                                                                  
        if(TIM3->SR&0X0001)//溢出中斷,當一個更新事件到來的時候,狀態(tài)寄存器的0位就會置位,否則為零
        {
                LED1=!LED1;                                                                                                                        
        }                                   
        TIM3->SR&=~(1<<0);//清除中斷標志位 ,0為無更新事件發(fā)生            
}
八、用timer3進行PWM輸出

1)首先是使能計數(shù)器3的時鐘,并且要使能相應管腳的時鐘
2)設置計數(shù)器復用相應管腳的輸出模式,一般是設置為推挽輸出
3)使能管腳復用時鐘
4)設置計數(shù)器自動重載值和預分頻器的值
5)設置PWM的輸出模式
6)使能預裝載寄存器
7)進行輸出使能和計數(shù)器使能
//TIM3 PWM部分初始化
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預分頻數(shù)
void TIM3_PWM_Init(u16 arr,u16 psc)
{                                                         
        //此部分需手動修改IO口設置
        RCC->APB1ENR|=1<<1;         //TIM3時鐘使能   
        RCC->APB2ENR|=1<<3;            //使能PORTB時鐘        
        GPIOB->CRL&=0XFF0FFFFF;        //PB5輸出
        GPIOB->CRL|=0X00B00000;        //復用功能輸出                    
           
        RCC->APB2ENR|=1<<0;     //開啟輔助時鐘           
        AFIO->MAPR&=0XFFFFF3FF; //清除MAPR的[11:10]
        AFIO->MAPR|=1<<11;      //部分重映像,TIM3_CH2->PB5

        TIM3->ARR=arr;                        //設定計數(shù)器自動重裝值
        TIM3->PSC=psc;                        //預分頻器不分頻
        
        TIM3->CCMR1|=7<<12;          //CH2 PWM2模式                 
        TIM3->CCMR1|=1<<11;         //CH2預裝載使能           
        TIM3->CCER|=1<<4;           //OC2 輸出使能           
        TIM3->CR1=0x0080;           //ARPE使能
        TIM3->CR1|=0x01;            //使能定時器3                                                                                          
}
九、輸入捕獲實驗 (以TIMER5為例)
1)開啟TIM5時鐘,配置PA0為下拉輸入
2)設置TIM5的ARR和PSC

3)設置TIM5的CCMR1
4)設置TIM5的CCER,開啟輸入捕獲,并設置為上升沿捕獲

5)設置TIM5的DIER,使能捕獲和更新中斷,并編寫中斷服務函數(shù)

6)設置TIM5的CR1,使能定時器

//定時器5通道1輸入捕獲配置
//arr:自動重裝值
//psc:時鐘預分頻數(shù)
void TIM5_Cap_Init(u16 arr,u16 psc)
{                 
        RCC->APB1ENR|=1<<3;           //TIM5 時鐘使能
        RCC->APB2ENR|=1<<2;            //使能PORTA時鐘  
         
        GPIOA->CRL&=0XFFFFFFF0;        //PA0 清除之前設置  
        GPIOA->CRL|=0X00000008;        //PA0 輸入   
        GPIOA->ODR|=0<<0;                //PA0 下拉
         
         TIM5->ARR=arr;                  //設定計數(shù)器自動重裝值   
        TIM5->PSC=psc;                  //預分頻器

        TIM5->CCMR1|=1<<0;                //CC1S=01         選擇輸入端 IC1映射到TI1上
         TIM5->CCMR1|=0<<4;                 //IC1F=0000 配置輸入濾波器 不濾波
         TIM5->CCMR1|=0<<10;         //IC2PS=00         配置輸入分頻,不分頻

        TIM5->CCER|=0<<1;                 //CC1P=0        上升沿捕獲
        TIM5->CCER|=1<<0;                 //CC1E=1         允許捕獲計數(shù)器的值到捕獲寄存器中

        TIM5->DIER|=1<<1;           //允許捕獲中斷                                
        TIM5->DIER|=1<<0;           //允許更新中斷        
        TIM5->CR1|=0x01;            //使能定時器2
        MY_NVIC_Init(2,0,TIM5_IRQn,2);//搶占2,子優(yōu)先級0,組2           
}

//捕獲狀態(tài)
//[7]:0,沒有成功的捕獲;1,成功捕獲到一次.
//[6]:0,還沒捕獲到高電平;1,已經(jīng)捕獲到高電平了.
//[5:0]:捕獲高電平后溢出的次數(shù)
u8  TIM5CH1_CAPTURE_STA=0;        //輸入捕獲狀態(tài),這里的TIM5CH1_CAPTURE_STA當做一個                                                        //寄存器來用                                                   
u16        TIM5CH1_CAPTURE_VAL;        //輸入捕獲值
//定時器5中斷服務程序         
void TIM5_IRQHandler(void)
{                     
        u16 tsr;
        tsr=TIM5->SR;
         if((TIM5CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲        ,第7位為捕獲完成標志位
        {
                if(tsr&0X01)//溢出
                {            
                        if(TIM5CH1_CAPTURE_STA&0X40)//已經(jīng)捕獲到高電平了
                        {
                                if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高電平太長了,捕獲標志位全部為1
                                {
                                        TIM5CH1_CAPTURE_STA|=0X80;//標記成功捕獲了一次
                                        TIM5CH1_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH1_CAPTURE_STA++;
                        }         
                }
                if(tsr&0x02)//捕獲1發(fā)生捕獲事件
                {        
                        if(TIM5CH1_CAPTURE_STA&0X40)                //捕獲到一個下降沿,由于前面已經(jīng)有了高電平的標志位了                 
                        {                                 
                                TIM5CH1_CAPTURE_STA|=0X80;                //標記成功捕獲到一次高電平脈寬
                            TIM5CH1_CAPTURE_VAL=TIM5->CCR1;        //獲取當前的捕獲值.
                                 TIM5->CCER&=~(1<<1);                        //CC1P=0 設置為上升沿捕獲
                        }else                                                                  //還未開始,第一次捕獲上升沿
                        {
                                TIM5CH1_CAPTURE_STA=0;                        //清空
                                TIM5CH1_CAPTURE_VAL=0;
                                TIM5CH1_CAPTURE_STA|=0X40;                //標記捕獲到了上升沿
                                 TIM5->CNT=0;                                        //計數(shù)器清空
                                 TIM5->CCER|=1<<1;                                 //CC1P=1 設置為下降沿捕獲
                        }                    
                }                                                                                    
         }
        TIM5->SR=0;//清除中斷標志位            
}
十、電容觸摸按鍵實驗
1)電容觸摸按鍵的原理是根據(jù)電容值不同充放電的時間不同,用定時器對電容的充電時間的計時比較,就可以判斷是否有被觸摸
Vc=V0*(1-e^(-t/RC))
其中Vc為電容電壓,V0為充電電壓,R為充電電阻,C為電容容值,e為自然底數(shù),t為充電時間。根據(jù)這個公式,我們就可以計算出Cs和Cx。先用開關將Cs(或Cs+Cx)上的電放盡,然后斷開開關,讓R給Cs(或Cs+Cx)充電,當沒有手指觸摸的時候,Cs的充電曲線如圖中的A曲線。而當有手指觸摸的時候,手指和TPAD之間引入了新的電容Cx,此時Cs+Cx的充電曲線如圖中的B曲線。從上圖可以看出,A、B兩種情況下,Vc達到Vth的時間分別為Tcs和Tcs+Tcx。,就已經(jīng)可以實現(xiàn)觸摸檢測了,當充電時間在Tcs附近,就可以認為沒有觸摸,而當充電時間大于Tcs+Tx時,就認為有觸摸按下(Tx為檢測閥值)。
2)、實驗方法如下:本章,我們使用PA1(TIM5_CH2)來檢測TPAD是否有觸摸,在每次檢測之前,我們先配置PA1為推挽輸出,將電容Cs(或Cs+Cx)放電,然后配置PA1為浮空輸入,利用外部上拉電阻給電容Cs(Cs+Cx)充電,同時開啟TIM5_CH2的輸入捕獲,檢測上升沿,當檢測到上升沿的時候,就認為電容充電完成了,完成一次捕獲檢測。
3)、實驗原理圖如下
//定時器5通道2輸入捕獲配置         
//arr:自動重裝值
//psc:時鐘預分頻數(shù)
void TIM5_CH2_Cap_Init(u16 arr,u16 psc)
{
        //此部分需手動修改 IO口設置  
         RCC->APB1ENR|=1<<3;           //TIM5 時鐘使能
        RCC->APB2ENR|=1<<2;            //使能PORTA時鐘

        GPIOA->CRL&=0XFFFFFF0F;        //PA1  輸入  
        GPIOA->CRL|=0X00000040;        //浮空輸入               
         
         TIM5->ARR=arr;                  //設定計數(shù)器自動重裝值//剛好1ms   
        TIM5->PSC=psc;                  //預分頻器,1M的計數(shù)頻率         

        TIM5->CCMR1|=1<<8;                //CC2S=01         選擇輸入端 IC2映射到TI2上
         TIM5->CCMR1|=0<<12;         //IC2F=0011 配置輸入濾波器 8個定時器時鐘周期濾波
         TIM5->CCMR1|=0<<10;         //IC2PS=00         配置輸入分頻,不分頻

        TIM5->CCER|=0<<5;                 //CC2P=0        上升沿捕獲
        TIM5->CCER|=1<<4;                 //CC2E=1         允許捕獲計數(shù)器的值到捕獲寄存器中
                                                                                                                                 
        TIM5->CR1|=0x01;            //使能定時器5
}
      
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品综合久久久久久五月天 | 亚洲一区二区在线 | 91精品在线播放 | 日韩亚洲一区二区 | www.久久久| 玖玖在线精品 | 国产精品亚洲欧美日韩一区在线 | 国产精品国产三级国产aⅴ中文 | 日韩欧美在线视频 | 欧美视频二区 | 国产精品久久久久久久 | 蜜月aⅴ国产精品 | 91啪亚洲精品 | 国产精品亚洲欧美日韩一区在线 | 人人九九精 | 久久婷婷香蕉热狠狠综合 | 西西裸体做爰视频 | 精品成人在线 | 日本精品一区二区三区在线观看视频 | 国产97久久| 国产网站在线 | 色接久久 | 国产视频1区 | 久久精品欧美一区二区三区麻豆 | 亚洲+变态+欧美+另类+精品 | 亚洲人人 | 午夜影院在线观看视频 | 国产一区二区三区在线观看免费 | 在线成人www免费观看视频 | 在线观看日韩 | 手机av在线 | 欧美白人做受xxxx视频 | 欧美大片一区二区 | 欧美精品导航 | 日韩伦理电影免费在线观看 | 亚洲国产精品一区二区第一页 | 日韩激情网 | 亚洲在线看 | 范冰冰一级做a爰片久久毛片 | 国产乱精品一区二区三区 | 久在线 |