主頁 >  其他 > EC11旋轉編碼器驅動程式

EC11旋轉編碼器驅動程式

2021-04-05 11:17:09 其他

EC11驅動程式

不多做介紹,百度上很多相關的介紹
首先,放上參考檔案
代碼有正轉、反轉、按下正轉、按下反轉、單機、雙擊、長按和長安松手檢測,有什么問題可以在下方留言

我是對該檔案代碼進行一些修改,偏向于我的習慣做的修改,
主要是作者的代碼在按下并旋轉的時候會觸發長按(也許是我移植的時候,改錯了什么所導致的)、雙擊,
我把它改為不觸發,并且讓函式做回傳值處理,最終的按鍵操作在主函式或者單獨寫一個設定,便于后續移植,

  • EncoderEC11.c
//---->>>>----檔案描述:EC11旋轉編碼器底層驅動程式---<<<<----//
//---->>>>----檔案版本:V1.0----<<<<----//
#include "EncoderEC11.h"

//-------->>>>>>>>--------注意事項:EC11旋轉編碼器的掃描時間間隔控制在1~4ms之間,否則5ms及以上的掃描時間在快速旋轉時可能會誤判旋轉方向--------<<<<<<<<--------//

//*******************************************************************/
//功能:初始化EC11旋轉編碼器相關引數
//形參:EC11旋轉編碼器的型別-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對應一脈沖;1(或非0)----兩定位對應一脈沖,
//回傳:無
//詳解:對EC11旋轉編碼器的連接IO口做IO口模式設定,以及將相關的變數進行初始化
//*******************************************************************/
void Encoder_EC11_Init(unsigned char Set_EC11_TYPE)
{
//    //IO口模式初始化,初始化EC11的IO口為準雙向模式
//    P35_QB();
//    P36_QB();
//    P37_QB();
    
    EC11_A_Now = 1;
    EC11_B_Now = 1;
    EC11_Key = 1;

    //EC11型別選擇:0-一定位一脈沖;1-兩定位一脈沖
    if(Set_EC11_TYPE == 0)
    {
        EC11_Type = 0;
    }
    else
    {
        EC11_Type = 1;
    }

    //避免上電時EC11旋鈕位置不確定導致一次動作誤判
    EC11_A_Last = EC11_A_Now;   
    EC11_B_Last = EC11_B_Now;

    //--------清除按鍵計數器和標志位--------//
    EC11_KEY_COUNT = 0;                     //EC11按鍵動作計數器
    EC11_KEY_DoubleClick_Count = 0;         //EC11按鍵雙擊動作計數器
    FLAG_EC11_KEY_ShotClick = 0;            //EC11按鍵短按動作標志
    FLAG_EC11_KEY_LongClick = 0;            //EC11按鍵長按動作標志
    FLAG_EC11_KEY_DoubleClick = 0;          //EC11按鍵雙擊動作標志
}


//*******************************************************************/
//功能:掃描EC11旋轉編碼器的動作并將引數回傳給動作分析函式使用
//形參:EC11旋轉編碼器的型別-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對應一脈沖;1(或非0)----兩定位對應一脈沖
//回傳:EC11旋轉編碼器的掃描結果-->>  char ScanResult  -->>  0:無動作;1:正轉; -1:反轉;2:只按下按鍵;3:按著按鍵正轉;-3:按著按鍵反轉
//詳解:只掃描EC11旋轉編碼器有沒有動作,不關心是第幾次按下按鍵或長按或雙擊,回傳值直接作為形參傳給 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函式使用
//*******************************************************************/
char Encoder_EC11_Scan()
{
//以下儲存A、B上一次值的變數宣告為靜態全域變數,方便對EC11對應的IO口做初始化
//  static char EC11_A_Last = 0;
//  static char EC11_B_Last = 0;
    char ScanResult = 0;    //回傳編碼器掃描結果,用于分析編碼器的動作
                            //回傳值的取值:   0:無動作;      1:正轉;           -1:反轉;  
                            //                  2:只按下按鍵;    3:按著按鍵正轉;   -3:按著按鍵反轉

                            //======================================================//
    if(EC11_Type == 0)      //================一定位對應一脈沖的EC11================//
    {                       //======================================================//
        if(EC11_A_Now != EC11_A_Last)   //以A為時鐘,B為資料,正轉時AB反相,反轉時AB同相
        {
            if(EC11_A_Now == 0)
            {
                if(EC11_B_Now ==1)      //只需要采集A的上升沿或下降沿的任意一個狀態,若A下降沿時B為1,正轉                    
                    ScanResult = 1;     //正轉

                else                    //反轉
                    ScanResult = -1;
            }
            EC11_A_Last = EC11_A_Now;   //更新編碼器上一個狀態暫存變數
            EC11_B_Last = EC11_B_Now;   //更新編碼器上一個狀態暫存變數
        }
    }   
                            //======================================================//
    else                    //================兩定位對應一脈沖的EC11================//
    {                       //======================================================//
        if(EC11_A_Now !=EC11_A_Last)        //當A發生跳變時采集B當前的狀態,并將B與上一次的狀態進行對比,
        {                                   //若A 0->1 時,B 1->0 正轉;若A 1->0 時,B 0->1 正轉;
                                            //若A 0->1 時,B 0->1 反轉;若A 1->0 時,B 1->0 反轉
            if(EC11_A_Now == 1)     //EC11_A和上一次狀態相比,為上升沿
            {
                if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次狀態相比,為下降沿
                    ScanResult = 1;                         //正轉

                if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次狀態相比,為上升沿               
                    ScanResult = -1;                        //反轉

                //>>>>>>>>>>>>>>>>下面為正轉一次再反轉或反轉一次再正轉處理<<<<<<<<<<<<<<<<//
                if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿時,采集的B不變且為0
                    ScanResult = 1;                                 //正轉

                if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿時,采集的B不變且為1
                    ScanResult = -1;                                //反轉
            }

            else                    //EC11_A和上一次狀態相比,為下降沿
            {
                if((EC11_B_Last == 1)&&(EC11_B_Now == 0))   //EC11_B和上一次狀態相比,為下降沿
                    ScanResult = -1;                        //反轉

                if((EC11_B_Last == 0)&&(EC11_B_Now == 1))   //EC11_B和上一次狀態相比,為上升沿
                    ScanResult = 1;                         //正轉

                //>>>>>>>>>>>>>>>>下面為正轉一次再反轉或反轉一次再正轉處理<<<<<<<<<<<<<<<<//
                if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 0))  //A上升沿時,采集的B不變且為0
                    ScanResult = -1;                                //反轉

                if((EC11_B_Last == EC11_B_Now)&&(EC11_B_Now == 1))  //A上升沿時,采集的B不變且為1   
                    ScanResult = 1;                                 //正轉

            }               
            EC11_A_Last = EC11_A_Now;   //更新編碼器上一個狀態暫存變數
            EC11_B_Last = EC11_B_Now;   //更新編碼器上一個狀態暫存變數
        }
    }                                                                       

    if(EC11_Key == 0)   //如果EC11的按鍵按下,并且沒有EC11沒有轉動,
    {
        if(ScanResult == 0)         //按下按鍵時未轉動
            ScanResult = 2;         //回傳值為2
        else
        {
            if(ScanResult == 1)     //按下按鍵時候正轉
                ScanResult = 3;     //回傳值為3
            if(ScanResult == -1)    //按下按鍵時候反轉
                ScanResult = -3;    //回傳值為-3
        }
    }

    return ScanResult;      //回傳值的取值:   0:無動作;      1:正轉;           -1:反轉;
}                           //              2:只按下按鍵;    3:按著按鍵正轉;   -3:按著按鍵反轉


//*******************************************************************/
//功能:對EC11旋轉編碼器的動作進行分析,并作出相應的動作處理代碼
//形參:無
//回傳:char AnalyzeResult = 0;目前無用,若在該函式里做了動作處理,則函式的回傳值無需理會
//詳解:對EC11旋轉編碼器的動作進行模式分析,是單擊還是雙擊還是長按松手還是一直按下,形參從 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函式傳入,在本函式內修改需要的動作處理代碼
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value)
{
		static bit FLAG_KEY_invalid;
    char AnalyzeResult = 0;
    static unsigned int TMP_Value = 0;  //中間計數值,用于連續長按按鍵的動作延時間隔
    //>>>>>>>>>>>>>>>>編碼器正轉處理程式<<<<<<<<<<<<<<<<//
    if(EC11_Value == 1) //正轉
    {
        //--------編碼器正轉動作代碼--------//
        AnalyzeResult = 1;
        
    }

    //>>>>>>>>>>>>>>>>編碼器反轉處理程式<<<<<<<<<<<<<<<<//
    else if(EC11_Value == -1)    //反轉
    {
        //--------編碼器反轉動作代碼--------//
        AnalyzeResult = 2;
        
    }


    //>>>>>>>>>>>>>>>>編碼器按鍵按下并正轉處理程式<<<<<<<<<<<<<<<<//
    else if(EC11_Value == 3)
    {
        //--------編碼器按鍵按下并正轉動作代碼--------//
        AnalyzeResult = 3;
        
    }

    //>>>>>>>>>>>>>>>>編碼器按鍵按下并反轉處理程式<<<<<<<<<<<<<<<<//
    else if(EC11_Value == -3)
    {
        //--------編碼器按鍵按下并反轉動作代碼--------//
        AnalyzeResult = 4;
        
    }

		if((AnalyzeResult == 3) || (AnalyzeResult == 4))//		按下并轉動
		{
			FLAG_KEY_invalid = 1;//使按鍵單操作無效
			EC11_KEY_COUNT = 0;
			FLAG_EC11_KEY_ShotClick = 0;
			FLAG_EC11_KEY_LongClick = 0;
			FLAG_EC11_KEY_DoubleClick = 0;
			EC11_KEY_DoubleClick_Count = 0;
		}

		if(FLAG_KEY_invalid == 0)
			{
				//>>>>>>>>>>>>>>>>編碼器按鍵按下處理程式<<<<<<<<<<<<<<<<//
				if(EC11_Value == 2)     //====檢測到按鍵按下====//
				{
						if(EC11_KEY_COUNT<10000)    //打開按鍵按下時間定時器
								EC11_KEY_COUNT++;
						if(EC11_KEY_COUNT == KEY_COUNT_DESHAKING)   //按下按鍵時間到達消抖時間時
						{                                           //置位短按按鍵標志
								FLAG_EC11_KEY_ShotClick = 1;
						}

						if((EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //松開按鍵后,又在定時器在雙擊時間內按下按鍵
						{                                                                                               //置位雙擊按鍵標志
								FLAG_EC11_KEY_DoubleClick = 1;
						}

						if(EC11_KEY_COUNT == KEY_COUNT_LONGTIME)    //按下按鍵時間到達長按時間
						{                                           //置位長按按鍵標志并復位短按按鍵標志
								FLAG_EC11_KEY_LongClick = 1;
								FLAG_EC11_KEY_ShotClick = 0;
						}

				}
				else                    //====檢測到按鍵松開====//     
				{
						if(EC11_KEY_COUNT < KEY_COUNT_DESHAKING)    //沒到消抖時長就松開按鍵,復位所有定時器和按鍵標志
						{
								EC11_KEY_COUNT = 0;
								FLAG_EC11_KEY_ShotClick = 0;
								FLAG_EC11_KEY_LongClick = 0;
								FLAG_EC11_KEY_DoubleClick = 0;
								EC11_KEY_DoubleClick_Count = 0;
						}
						else
						{
								
								if(FLAG_EC11_KEY_ShotClick == 1)        //短按按鍵定時有效期間
								{
										if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count >= 0)) 
												EC11_KEY_DoubleClick_Count++;
										if((FLAG_EC11_KEY_DoubleClick == 1)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME))   //如果在規定雙擊時間內再次按下按鍵
										{                                                                                               //認為按鍵是雙擊動作
												FLAG_EC11_KEY_DoubleClick = 2;
										}   

										if((FLAG_EC11_KEY_DoubleClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME))    //如果沒有在規定雙擊時間內再次按下按鍵
												FLAG_EC11_KEY_ShotClick = 0;                                                                //認為按鍵是單擊動作
								}

								if(FLAG_EC11_KEY_LongClick == 1)        //檢測到長按按鍵松開
										FLAG_EC11_KEY_LongClick = 0;
						}

				}

		
			//>>>>>>>>>>>>>>>>編碼器按鍵分析處理程式<<<<<<<<<<<<<<<<//
			if(EC11_KEY_COUNT > KEY_COUNT_DESHAKING)    //短按按鍵延時到了時間
			{

					//短按按鍵動作結束代碼
					if((FLAG_EC11_KEY_ShotClick == 0)&&(EC11_KEY_DoubleClick_Count > KEY_COUNT_DUALCLICKTIME)&&(EC11_KEY_COUNT < KEY_COUNT_LONGTIME))   //短按按鍵動作結束代碼
					{
							//--------短按按鍵動作結束代碼--------//
							AnalyzeResult = 5;
							//--------清除標志位--------//
							EC11_KEY_COUNT = 0;
							EC11_KEY_DoubleClick_Count = 0;
							FLAG_EC11_KEY_DoubleClick = 0;
					}

					//雙擊按鍵動作結束代碼
					if((FLAG_EC11_KEY_DoubleClick == 2)&&(EC11_KEY_DoubleClick_Count > 0)&&(EC11_KEY_DoubleClick_Count <= KEY_COUNT_DUALCLICKTIME)) //雙擊按鍵動作結束代碼
					{
							//--------雙擊按鍵動作結束代碼--------//
							AnalyzeResult = 6;
							//--------清除標志位--------//
							EC11_KEY_COUNT = 0;
							EC11_KEY_DoubleClick_Count = 0;
							FLAG_EC11_KEY_ShotClick = 0;
							FLAG_EC11_KEY_DoubleClick = 0;
							
					}

					//連續長按按鍵按下代碼
					if((FLAG_EC11_KEY_LongClick == 1)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //連續長按按鍵按下代碼
					{
							TMP_Value ++;
							if(TMP_Value % KEY_LONG_REPEAT_TIME == 0)
							{
									TMP_Value = 0;
									//-------連續長按按鍵按下代碼--------//
									AnalyzeResult = 8;
							}
					}

					//長按按鍵動作結束代碼
					if((FLAG_EC11_KEY_LongClick == 0)&&(EC11_KEY_COUNT >= KEY_COUNT_LONGTIME))  //長按按鍵動作結束代碼
					{                                                                           
							//--------長按按鍵按下動作結束代碼--------//
							AnalyzeResult = 7;
							//--------清除標志位--------//
							EC11_KEY_COUNT = 0;
					}
			}		
		}
		
		if(EC11_Key == 1)
		{
			FLAG_KEY_invalid = 0;
		}
    return AnalyzeResult;
		//1:正轉
//		2:反轉
//		3:按下并正轉
//		4:按下并反轉
//		5:短按
//		6:雙擊
//		7:長按結束
//		8:長按
}

  • EncoderEC11.h
//---->>>>----檔案描述:EC11旋轉編碼器底層驅動程式---<<<<----//
//---->>>>----檔案版本:V1.0----<<<<----//
#ifndef __EncoderEC11_H
#define __EncoderEC11_H

//#include    "config.H"
#include <stc8.h>

//----------------IO口定義----------------//
#define EC11_A_Now                  P00                             //EC11的A引腳,視為時鐘線
#define EC11_B_Now                  P01                             //EC11的B引腳,視為信號線
#define EC11_Key                    P02                             //EC11的按鍵

//----------------編碼器動作代碼相關定義----------------//
extern  int G_PWM_NUM1;
extern  int G_PWM_NUM2;
extern  int G_PWM_NUM3;
static unsigned char EC11_NUM_SW = 0;

//----------------編碼器引數微調宏定義----------------//
#define EC11_SCAN_PERIOD_MS            1                            //EC11編碼器掃描周期
#define KEY_COUNT_DESHAKING         ( 20/EC11_SCAN_PERIOD_MS)       //按鍵消抖時間
#define KEY_COUNT_LONGTIME          (600/EC11_SCAN_PERIOD_MS)       //長按按鍵判斷時間
#define KEY_COUNT_DUALCLICKTIME     (150/EC11_SCAN_PERIOD_MS)       //雙擊按鍵判斷時間
#define KEY_LONG_REPEAT_TIME        (200/EC11_SCAN_PERIOD_MS)       //長按按鍵的回報率的倒數,即一直長按按鍵時回應的時間間隔

//----------------區域檔案內變數串列----------------//
static  char    EC11_A_Last = 0;                        //EC11的A引腳上一次的狀態
static  char    EC11_B_Last = 0;                        //EC11的B引腳上一次的狀態
static  char    EC11_Type = 1;                          //定義變數暫存EC11的型別---->>>>----  0:一定位對應一脈沖;  1:兩定位對應一脈沖
                                                        //所謂一定位對應一脈沖,是指EC11旋轉編碼器每轉動一格,A和B都會輸出一個完整的方波,
                                                        //而  兩定位對應一脈沖,是指EC11旋轉編碼器每轉動兩格,A和B才會輸出一個完整的方波,只轉動一格只輸出A和B的上升沿或下降沿
                                                        
static   int    EC11_KEY_COUNT = 0;                     //EC11按鍵動作計數器
static   int    EC11_KEY_DoubleClick_Count = 0;         //EC11按鍵雙擊動作計數器
static  char    FLAG_EC11_KEY_ShotClick = 0;            //EC11按鍵短按動作標志
static  char    FLAG_EC11_KEY_LongClick = 0;            //EC11按鍵長按動作標志
static  char    FLAG_EC11_KEY_DoubleClick = 0;          //EC11按鍵雙擊動作標志



//----------------函式快速呼叫(復制粘貼)串列----------------//
//
/*******************************************************************
void Encoder_EC11_Init(unsigned char Set_EC11_TYPE);        //初始化EC11旋轉編碼器IO口和型別以及變數初始化
char Encoder_EC11_Scan();                                   //掃描旋轉編碼器的動作
void Encoder_EC11_Analyze(char EC11_Value);                 //分析EC11旋轉編碼器的動作以及動作處理代碼
******************************************************************/
//-------->>>>>>>>--------注意事項:EC11旋轉編碼器的掃描時間間隔控制在1~4ms之間,否則5ms及以上的掃描時間在快速旋轉時可能會誤判旋轉方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事項:EC11旋轉編碼器的掃描時間間隔控制在1~4ms之間,否則5ms及以上的掃描時間在快速旋轉時可能會誤判旋轉方向--------<<<<<<<<--------//
//-------->>>>>>>>--------注意事項:EC11旋轉編碼器的掃描時間間隔控制在1~4ms之間,否則5ms及以上的掃描時間在快速旋轉時可能會誤判旋轉方向--------<<<<<<<<--------//

//----------------函式宣告串列----------------//
//
//*******************************************************************/
//功能:初始化EC11旋轉編碼器相關引數
//形參:EC11旋轉編碼器的型別-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對應一脈沖;1(或非0)----兩定位對應一脈沖,
//回傳:無
//詳解:對EC11旋轉編碼器的連接IO口做IO口模式設定,以及將相關的變數進行初始化
//*******************************************************************/
void Encoder_EC11_Init(unsigned char Set_EC11_TYPE);

//*******************************************************************/
//功能:掃描EC11旋轉編碼器的動作并將引數回傳給動作分析函式使用
//形參:EC11旋轉編碼器的型別-->>  unsigned char Set_EC11_TYPE  <<--  :0----一定位對應一脈沖;1(或非0)----兩定位對應一脈沖
//回傳:EC11旋轉編碼器的掃描結果-->>  char ScanResult  -->>  0:無動作;1:正轉; -1:反轉;2:只按下按鍵;3:按著按鍵正轉;-3:按著按鍵反轉
//詳解:只掃描EC11旋轉編碼器有沒有動作,不關心是第幾次按下按鍵或長按或雙擊,回傳值直接作為形參傳給 [ void Encoder_EC11_Analyze(char EC11_Value); ] 函式使用
//*******************************************************************/
char Encoder_EC11_Scan();
    
//*******************************************************************/
//功能:對EC11旋轉編碼器的動作進行分析,并作出相應的動作處理代碼
//形參:無
//回傳:char AnalyzeResult = 0;目前無用,若在該函式里做了動作處理,則函式的回傳值無需理會
//詳解:對EC11旋轉編碼器的動作進行模式分析,是單擊還是雙擊還是長按松手還是一直按下,形參從 [ char Encoder_EC11_Scan(unsigned char Set_EC11_TYPE) ] 函式傳入,在本函式內修改需要的動作處理代碼
//*******************************************************************/
char Encoder_EC11_Analyze(char EC11_Value);

#endif


//---->>>>----函式使用示例----<<<<----//
/********

#include "config.h"
#include "delay.h"
#include "EncoderEC11.h"


int cnt = -1;                                                                   //流水燈速查表偏移變數
unsigned char disp_tmp[] = {~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80};   //流水燈速查表

void Timer0Init(void)       //1毫秒@22.1184MHz
{
    AUXR &= 0x7F;       //定時器時鐘12T模式
    TMOD &= 0xF0;       //設定定時器模式
    TL0 = 0xCD;     //設定定時初值
    TH0 = 0xF8;     //設定定時初值
    TF0 = 0;        //清除TF0標志
    TR0 = 1;        //定時器0開始計時
}

void main()
{

    P1_QB_ALL();
    P2_QB_ALL();
    P3_QB_ALL();
    delay_ms(50);  //延時100毫秒等待所有MCU復位

    Encoder_EC11_Init(1);

    EA = 1;
    ET0 = 1;
    Timer0Init();
    while(1)
    {
            
    }
 
}

//-------->>>>>>>>--------注意事項:EC11旋轉編碼器的掃描時間間隔控制在1~4ms之間,否則5ms及以上的掃描時間在快速旋轉時可能會誤判旋轉方向--------<<<<<<<<--------//
void T0_ISR() interrupt 1
{
    static int tmp =0;
    Encoder_EC11_Analyze(Encoder_EC11_Scan());
    if(P33 == 0)
    {
        tmp ++;
        if(tmp == 500)
        {
            tmp =0;
            P27 = !P27;
        }
    }   
}


********/

這里我買的編碼旋鈕不知道為什么無法把單片機準雙向模式的IO口拉低(拿示波器才發現),于是設定為開漏模式,也可以設定為高阻模式

  • main.c
#include "EncoderEC11.h"
#include <stc8.h>
#include <stdio.h>

void Timer0Init(void);		//1毫秒@24.000MHz
void UartInit(void);		//115200bps@24.000MHz
void SeriPushSend(unsigned char *pStr);

//int dat;

void main(void)
{
//	char str[5];
	P0M0 = 0xFF;//設定為開漏模式
	P0M1 = 0XFF;
	UartInit();		//115200bps@24.000MHz
	Timer0Init();		//1毫秒@24.000MHz
	Encoder_EC11_Init(0);//0-一定位對應一脈沖;1-兩定位對應一脈沖
	ET0 = 1;
	EA = 1;
	while(1)
	{
//		if(dat)
//		{
//			sprintf(str,"%d\r\n",dat);
//			SeriPushSend(str);
//			dat = 0;
//		}
	}
}

void timer0(void)	interrupt 1
{
	static int dat;
	char str[5];
	dat = Encoder_EC11_Analyze(Encoder_EC11_Scan());
	if(dat)
	{
		sprintf(str,"%d\r\n",dat);
		SeriPushSend(str);
//		dat = 0;
	}
}

void Timer0Init(void)		//1毫秒@24.000MHz
{
	AUXR |= 0x80;		//定時器時鐘1T模式
	TMOD &= 0xF0;		//設定定時器模式
	TL0 = 0x40;		//設定定時初值
	TH0 = 0xA2;		//設定定時初值
	TF0 = 0;		//清除TF0標志
	TR0 = 1;		//定時器0開始計時
}
void UartInit(void)		//115200bps@24.000MHz
{
	SCON = 0x50;		//8位資料,可變波特率
	AUXR |= 0x40;		//定時器1時鐘為Fosc,即1T
	AUXR &= 0xFE;		//串口1選擇定時器1為波特率發生器
	TMOD &= 0x0F;		//設定定時器1為16位自動重裝方式
	TL1 = 0xCC;		//設定定時初值
	TH1 = 0xFF;		//設定定時初值
	ET1 = 0;		//禁止定時器1中斷
	TR1 = 1;		//啟動定時器1
}
void SeriPushSend(unsigned char *pStr)
{
	while(*pStr != '\0')//不是字串結尾就一直執行
	{
		SBUF = *pStr;//首先發送第“0”個字串
		while(TI == 0);//等待TI由硬體置一
		TI = 0;//TI置零
		pStr++;//地址++
	}
}

希望看完原作者文章的你,也能去注冊并點個贊

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272560.html

標籤:其他

上一篇:keil RTE HAL庫 STM32CubeMX 串口收發

下一篇:STM32

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more