【STC15库函数上手笔记】9、硬件SPI
目錄
- 硬件知識
- 庫函數
- spi.c
- spi.h
- 測試
- main.c
- 實驗現象
STC實驗箱4
IAP15W4K58S4
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
硬件知識
???????摘自《STC15系列單片機器件手冊》
???????STC15系列單片機還提供另一種高速串行通信接口——SPI接口。SPI是一種全雙工、高速、同步的通信總線,有兩種操作模式:主模式和從模式。在主模式中支持高達3Mbps的速率(工作頻率為12MHz時,如果CPU主頻采用20MHz到36MHz,則可更高,從模式時速度無法太快,SYSclk/4以內較好),還具有傳輸完成標志和寫沖突標志保護。
???????下表總結了STC15系列單片機內部集成了SPI功能的單片機型號:
???????上表中√表示對應的系列有相應的功能。
???????STC15W系列與STC15F/L系列具有不同的SPI時鐘頻率,其中,STC15W系列單片機的SPI時鐘頻率選擇如下表所列:
???????表中,CPU_CLK是CPU時鐘。
???????STC15F/L系列單片機的SPI時鐘頻率選擇如下表所列:
???????表中,CPU_CLK是CPU時鐘。
庫函數
SPI的庫函數僅在官方例程中發現,未與其他庫函數放在一起,請謹慎使用。
spi.c
/*------------------------------------------------------------------*/ /* --- STC MCU International Limited -------------------------------*/ /* --- STC 1T Series MCU RC Demo -----------------------------------*/ /* --- Mobile: (86)13922805190 -------------------------------------*/ /* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/ /* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/ /* --- Web: www.GXWMCU.com -----------------------------------------*/ /* --- QQ: 800003751 ----------------------------------------------*/ /* If you want to use the program or the program referenced in the */ /* article, please specify in which data and procedures from STC */ /*------------------------------------------------------------------*/#include "spi.h"u8 SPI_TxRxMode; // u8 SPI_TxWrite; u8 SPI_TxRead; u8 SPI_RxCnt; u8 SPI_RxTimerOut; u8 SPI_BUF_type SPI_RxBuffer[SPI_BUF_LENTH]; u8 SPI_BUF_type SPI_TxBuffer[SPI_BUF_LENTH]; bit B_SPI_TxBusy = 0; bit B_SPI_RxOk;//======================================================================== // 函數: void SPI_Init(SPI_InitTypeDef *SPIx) // 描述: SPI初始化程序. // 參數: SPIx: 結構參數,請參考spi.h里的定義. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void SPI_Init(SPI_InitTypeDef *SPIx) {if(SPIx->SPI_SSIG == ENABLE) SPCTL &= ~(1<<7); //enable SS, conform Master or Slave by SS pin.else SPCTL |= (1<<7); //disable SS, conform Master or Slave by SPI_Modeif(SPIx->SPI_Module == ENABLE) SPCTL |= (1<<6); //SPI enableelse SPCTL &= ~(1<<6); //SPI disableif(SPIx->SPI_FirstBit == SPI_LSB) SPCTL |= ~(1<<5); //LSB firstelse SPCTL &= ~(1<<5); //MSB firstif(SPIx->SPI_Mode == SPI_Mode_Slave) SPCTL &= ~(1<<4); //slaveelse SPCTL |= (1<<4); //masterif(SPIx->SPI_CPOL == SPI_CPOL_High) SPCTL |= (1<<3); //SCLK Idle High, Low Active.else SPCTL &= ~(1<<3); //SCLK Idle Low, High Active.if(SPIx->SPI_CPHA == SPI_CPHA_2Edge) SPCTL |= (1<<2); //sample at the second edgeelse SPCTL &= ~(1<<2); //sample at the first edgeif(SPIx->SPI_Interrupt == ENABLE) IE2 |= (1<<1);else IE2 &= ~(1<<1);SPCTL = (SPCTL & ~3) | (SPIx->SPI_Speed & 3); //set speedAUXR1 = (AUXR1 & ~(3<<2)) | SPIx->SPI_IoUse; }//======================================================================== // 函數: void SPI_SetMode(u8 mode) // 描述: SPI設置主從模式函數. // 參數: mode: 指定模式, 取值 SPI_Mode_Master 或 SPI_Mode_Slave. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void SPI_SetMode(u8 mode) {SPI_TxRxMode = mode;if(mode == SPI_Mode_Slave) SPCTL &= ~(1<<4); //slaveelse SPCTL |= (1<<4); //master }//======================================================================== // 函數: void SPI_WriteToTxBuf(u8 dat) // 描述: SPI裝載發送緩沖函數. // 參數: dat: 要發送的值. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void SPI_WriteToTxBuf(u8 dat) //寫入發送緩沖,指針+1 {SPI_TxBuffer[SPI_TxWrite] = dat;if(++SPI_TxWrite >= SPI_BUF_LENTH) SPI_TxWrite = 0; }//======================================================================== // 函數: void SPI_TrigTx(void) // 描述: SPI觸發發送函數, 將SPI模式設置為發送模式并將發送緩沖的數據發出. // 參數: dat: 要發送的值. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void SPI_TrigTx(void) {u8 i;if(SPI_TxRead == SPI_TxWrite) {B_SPI_TxBusy = 0;return;}B_SPI_TxBusy = 1;SPI_SetMode(SPI_Mode_Master);SPI_SS = 0;i = SPI_TxBuffer[SPI_TxRead];if(++SPI_TxRead >= SPI_BUF_LENTH) SPI_TxRead = 0;SPDAT = i; }//======================================================================== // 函數: void SPI_Transivion (void) interrupt SPI_VECTOR // 描述: SPI中斷函數. // 參數: none. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void SPI_Transivion (void) interrupt SPI_VECTOR {if(SPI_TxRxMode == SPI_Mode_Slave){// if(!B_SPI_RxOk){if(SPI_RxCnt >= SPI_BUF_LENTH) SPI_RxCnt = 0;SPI_RxBuffer[SPI_RxCnt++] = SPDAT;SPI_RxTimerOut = 5;}}if(SPI_TxRxMode == SPI_Mode_Master){if(SPI_TxRead != SPI_TxWrite){SPDAT = SPI_TxBuffer[SPI_TxRead];if(++SPI_TxRead >= SPI_BUF_LENTH) SPI_TxRead = 0;}else{SPI_TxRxMode = SPI_Mode_Slave;SPCTL &= ~(1<<4); //slaveSPI_SS = 1;B_SPI_TxBusy = 0;}}SPSTAT = SPIF + WCOL; //清0 SPIF和WCOL標志 }spi.h
/*------------------------------------------------------------------*/ /* --- STC MCU International Limited -------------------------------*/ /* --- STC 1T Series MCU RC Demo -----------------------------------*/ /* --- Mobile: (86)13922805190 -------------------------------------*/ /* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/ /* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/ /* --- Web: www.GXWMCU.com -----------------------------------------*/ /* --- QQ: 800003751 ----------------------------------------------*/ /* If you want to use the program or the program referenced in the */ /* article, please specify in which data and procedures from STC */ /*------------------------------------------------------------------*/#ifndef __SPI_H #define __SPI_H#include "config.h"#define SPI_BUF_LENTH 32 #define SPI_BUF_type idata#define SPI_Mode_Master 1 #define SPI_Mode_Slave 0 #define SPI_CPOL_High 1 #define SPI_CPOL_Low 0 #define SPI_CPHA_1Edge 1 #define SPI_CPHA_2Edge 0 #define SPI_Speed_4 0 #define SPI_Speed_16 1 #define SPI_Speed_64 2 #define SPI_Speed_128 3 #define SPI_MSB 0 #define SPI_LSB 1 #define SPI_P12_P13_P14_P15 (0<<2) #define SPI_P24_P23_P22_P21 (1<<2) #define SPI_P54_P40_P41_P43 (2<<2)typedef struct {u8 SPI_Module; //ENABLE,DISABLEu8 SPI_SSIG; //ENABLE, DISABLEu8 SPI_FirstBit; //SPI_MSB, SPI_LSBu8 SPI_Mode; //SPI_Mode_Master, SPI_Mode_Slaveu8 SPI_CPOL; //SPI_CPOL_High, SPI_CPOL_Lowu8 SPI_CPHA; //SPI_CPHA_1Edge, SPI_CPHA_2Edgeu8 SPI_Interrupt; //ENABLE,DISABLEu8 SPI_Speed; //SPI_Speed_4, SPI_Speed_16,SPI_Speed_64,SPI_Speed_128u8 SPI_IoUse; //SPI_P12_P13_P14_P15, SPI_P24_P23_P22_P21, SPI_P54_P40_P41_P43 } SPI_InitTypeDef;extern u8 SPI_TxRxMode; extern u8 SPI_TxWrite; extern u8 SPI_TxRead; extern u8 SPI_RxCnt; extern u8 SPI_RxTimerOut; extern u8 SPI_BUF_type SPI_RxBuffer[SPI_BUF_LENTH]; extern u8 SPI_BUF_type SPI_TxBuffer[SPI_BUF_LENTH]; extern u8 *SPI_pTxBuffer; extern bit B_SPI_RxOk; extern bit B_SPI_TxBusy;void SPI_Init(SPI_InitTypeDef *SPIx); void SPI_SetMode(u8 mode); void SPI_WriteToTxBuf(u8 dat); void SPI_TrigTx(void);#endif測試
OLED驅動程序見SPI驅動0.96/1.3寸 OLED屏幕,易修改為DMA控制
main.c
#include "./Drivers/config.h" #include "./Drivers/delay.h"#include "./Drivers/GPIO.h" #include "./Drivers/spi.h" #include "./SPI_OLED/oled.h"void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //結構定義GPIO_InitStructure.Mode = GPIO_OUT_PP; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2,&GPIO_InitStructure); //初始化為推挽輸出GPIO_InitStructure.Mode = GPIO_OUT_OD; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_2; //指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2,&GPIO_InitStructure); }void SPI_config(void) {SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Module = ENABLE; //SPI啟動 ENABLE, DISABLESPI_InitStructure.SPI_SSIG = DISABLE; //片選位 ENABLE, DISABLESPI_InitStructure.SPI_FirstBit = SPI_MSB; //移位方向 SPI_MSB, SPI_LSBSPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主從選擇 SPI_Mode_Master, SPI_Mode_SlaveSPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //時鐘相位 SPI_CPOL_High, SPI_CPOL_LowSPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數據邊沿 SPI_CPHA_1Edge, SPI_CPHA_2EdgeSPI_InitStructure.SPI_Interrupt = ENABLE; //中斷允許 ENABLE,DISABLESPI_InitStructure.SPI_Speed = SPI_Speed_128; //SPI速度 SPI_Speed_4, SPI_Speed_16, SPI_Speed_64, SPI_Speed_128SPI_InitStructure.SPI_IoUse = SPI_P24_P23_P22_P21; //IO口切換 SPI_P12_P13_P14_P15, SPI_P24_P23_P22_P21, SPI_P54_P40_P41_P43SPI_Init(&SPI_InitStructure);SPI_TxRxMode = SPI_Mode_Master; }void main(void) {uint8_t i;GPIO_config();SPI_config();EA = 1;OLED_Init();OLED_Clear();OLED_Display_On(); OLED_ShowString(0, 0, "STC15W4K58 OLED", 16, 0);OLED_ShowString(0, 2, " 2022-01-10", 6, 0);OLED_ShowString(0, 3, " SPI Test", 6, 0);for(i = 0; i < 7; ++i)OLED_ShowChinese(8 + 16 * i, 6, i, 1);OLED_Refresh_Gram();while(1){} }修改OLED_WR_Byte函數
實驗現象
總結
以上是生活随笔為你收集整理的【STC15库函数上手笔记】9、硬件SPI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国节点服务器有什么优势,美国CN2服务
- 下一篇: TP5:缩短访问路径和路由的使用——2