1. 程式人生 > >初識STM8S105K心得!

初識STM8S105K心得!

MCU.jpg

    最近由於公司專案需要STM8S105K這顆晶片,這兩天我也搗鼓了下,正好現在開通了部落格,以此記錄下自己的工作。

    開發環境:

        window10作業系統;

        IAR for STM8;

    開發工具;

        window10電腦;

        STM8S105K4t6最小系統;

        ST-link燒錄器

   本人之前工作上主要使用STM32晶片,開發STM8S時,是使用ST的庫開發還是直接操作暫存器開發的選擇上,考慮到STM32上主要使用的庫,而STM8S是八位微控制器,暫存器相對於STM32簡單不少,故本人使用暫存器操作開發。我以講解程式案列來與大家分享心得。

 實驗案例使用到的資源:

  1,IO口的位操作

  2,串列埠傳送以及串列埠接收與空閒中斷

  3,定時器1的使用

    首先,使用IAR新建一個基礎工程,工程截圖如下:

blob.png

    對於STM8S的IO口操作,我們可以向使用51微控制器那樣簡單直接位操作,我通過巨集定義來對於位操作:

#define LED0_Toggle PE_ODR_bit.ODR5 = !PE_ODR_bit.ODR5 //LED接在PE5上
#define LED1_Toggle PC_ODR_bit.ODR1 = !PC_ODR_bit.ODR1 //LED接在PC1上
#define LED0 PE_ODR_bit.ODR5
#define LED1 PC_ODR_bit.ODR1

    上面程式碼中對於了兩個LED燈,然後配置下IO口就可以實現燈的亮滅,IO配置如下:

 void GPIO_init(void)
{
PE_DDR = (1<<5); // 配置PE埠的方向暫存器PD3輸出
PE_CR1 = (1<<5); // 設定PE5為推輓輸出

PC_DDR = (1<<1); // 配置PC埠的方向暫存器PD3輸出
PC_CR1 = (1<<1); // 設定PC1為推輓輸出
}

    STM8S的串列埠使用前,我們實現要清楚STM8S的系統時鐘,我使用的時STM8S的內部16M時鐘作為時鐘源,然後1分頻作為系統時鐘,時鐘設定程式碼如下:

/*******************************************************************************
* 函式名 : CLK_init
* 描述 : 內部16M時鐘作為系統時鐘
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void CLK_init(void)
{

CLK_CKDIVR = 0x00; // 16M內部RC經1分頻後系統時鐘為16M

}

    我們知道系統設定後對串列埠波特率就好計算了。串列埠設定:波特率115200,資料位8,停止位1,奇偶校驗None,串列埠初始化主要進行串列埠引數設定,使能傳送與接收,以及開通接收中斷與空閒中斷,最後開啟總中斷。初始化函式如下:

/*******************************************************************************
* 函式名 : GPIO_init
* 描述 : GPIO初始化
* 輸入 :
* 輸出 :
* 返回 :
* 注意 :
*******************************************************************************/
void UART2_Init(void)
{
asm("sim"); // 關全域性中斷
/*暫存器恢復到預設值*/
UART2_CR3 = 0x00;
UART2_CR2 = 0x00;
UART2_CR3 = 0x00;

UART2_CR2 = 0x3c; //使能傳送和接收,及使能接收中斷和空閒中斷

UART2_BRR2 = 0x0b;//波特率115200
UART2_BRR1 = 0x08;
asm("rim"); // 關全域性中斷
}

    STM8S串列埠接收資料,我使用接收中斷和空閒中斷來完成資料的接收。當傳送字串時,每收到一個字元時觸發接收中斷,而只有當資料接收完檢測到空閒時才觸發空閒中斷,中斷程式碼如下:

#pragma vector=UART2_R_RXNE_vector
__interrupt void UART2_RX_IRQHandler(void)
{
static unsigned char i=0;
static unsigned char RXBuff[20];


if(UART2_SR&0x20)
{

RXBuff[i++]=UART2_DR;//對UART_DR的讀操作可以將該位清零
;
}
if(UART2_SR&0x10)
{

printf("%s \n",RXBuff);
i=UART2_SR; //對UART_DR的讀操作可以將該位清零
i=UART2_DR;
i=0;

}

}

    而串列埠傳送資料使用printfd的話就很方便,我也新增實現printf的程式碼,程式碼如下:

/*******************************************************************************
* 函式名:UART2_SendByte
* 描述 :uart傳送一個字元
* 輸入 :u8 Dat 傳送的字元
* 輸出 :無
* 返回 :
* 注意 :
*******************************************************************************/
void UART2_SendByte(unsigned char dat)
{
UART2_DR = dat;
while(!(UART2_SR&0x40)); //傳送標誌位是否為空
}

/*******************************************************************************
* 函式名:UART2_SendString
* 描述 :uart傳送字串
* 輸入 :u8* Data,u16 len
* 輸出 :無
* 返回 :
* 注意 :
*******************************************************************************/
void UART2_SendString(unsigned char* Data,unsigned short len)
{
unsigned short i=0;
for(;i<len;i++)
UART2_SendByte(Data[i]);

}

/*******************************************************************************
* 函式名:fputc
* 描述 :重定向c庫函式printf到USART1
* 輸入 :無
* 輸出 :無
* 返回 :
* 注意 : 由printf呼叫
*******************************************************************************/
int fputc(int ch, FILE *f)
{
/*將Printf內容發往串列埠*/
UART2_SendByte(ch);
return (ch);
}

     關於定時器的使用,比較簡單,主要實現LED燈的亮滅,我就不多講,附上程式碼,程式碼上有很多註釋,程式碼如下

/*******************************************************************************
* 函式名 : TIM1_init
* 描述 : 定時器1初始化
* 輸入 :
* 輸出 :
* 返回 :
* 注意 : 中斷週期500ms
*******************************************************************************/
void TIM1_init(void)
{
asm("sim"); // 關全域性中斷
TIM1_PSCRH = 0x3F; // 8M系統時鐘經預分頻f=fck/(PSCR+1)
TIM1_PSCRL = 0x7F; // PSCR=0x1F3F,f=16M/(0x3F7F+1)=1000Hz,每個計數週期1ms
TIM1_ARRH = 0x01; // 自動過載暫存器ARR=0x01F4=500
TIM1_ARRL = 0xF4; // 每記數500次產生一次中斷,即500ms
TIM1_IER = 0x01; // 允許更新中斷
TIM1_CR1 = 0x01; // 計數器使能,開始計數
asm("rim"); // 開全域性中斷
}



/*******************************************************************************
* 函式名 : TIM1_OVR_UIF
* 描述 : 定時器1中斷函式,處理中斷事物
* 輸入 :
* 輸出 :
* 返回 :
* 注意 : 一點要清除中斷標誌
*******************************************************************************/
#pragma vector=TIM1_OVR_UIF_vector
__interrupt void TIM1_OVR_UIF(void)
{
if(TIM1_SR1&0x01)
{
LED0=!LED0;
LED1=!LED1;
TIM1_SR1= 0x00; // 清除更新中斷標記,這步不能漏掉,否則會連續進入中斷程式
}

}

    最後我把工程程式碼上傳,以供大家下載,如有不妥,歡迎大家留言。

TEST_Pro.rar