亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
STM8L的I2C基本讀寫方法詳解 含例程
[打印本頁]
作者:
51hei小林
時間:
2016-10-10 00:52
標題:
STM8L的I2C基本讀寫方法詳解 含例程
STM8L的硬件I2C支持100KHz~400KHz的讀寫速度,作為主設備使用時,不需要配置IO,開啟I2C硬件后,對應的IO會自動啟用復用功能。本文選取24C02作為I2C從設備,STM8L作為主設備,進行I2C讀寫功能測試。
STM8L作為I2C主設備時,官方的數據手冊給出的配置流程如下圖:
詳細配置I2C為主設備的流程如下:
①打開I2C外設時鐘
②I2C輸入時鐘頻率大小選擇
③配置時鐘控制寄存器
④配置上升沿時間寄存器
⑤開啟I2C功能
STM8L的I2C默認為從設備,當發送一個START信號后,自動從從模式轉成主模式.
STM8L的I2C的實現寫一字節的描述如下:
①CR2寄存器中的START位被置位后,發送一個起始信號,SR1中的SB被硬件置位.讀取SR1寄存器,清除該標志位.
②向DR寄存器寫入從設備地址,SR1中的ADDR會被硬件置位,通過讀SR1,然后再讀SR3,清除該標志位.
③DR寄存器為空后,將從設備寄存器地址寫入DR
④DR寄存器為空后,將從要寫入的數據寫入DR
STM8L讀取一字節數據,這里不在贅述.
注意:I2C的時鐘頻率為2M以下時,根據數據手冊,在檢測到SB,ADDR,BTF,這些標志位后,必須在其后插入5個NOP再清除標志位.
STM8S中文文檔中,對此描述如下.
/*硬件連接*/
// PC0<--->SDA PC1---->SCL
/****************************************************************************************
*開發環境:IAR for stm8 v6.5.3
*硬件平臺:STM8L-DISCOVERY
*功能說明:通過硬件I2C等待的方法,實現對24C02寄存器的讀寫,借助IAR軟件的調試功能,查看變量的數值
*作 者:茗風
****************************************************************************************/
#include"iostm8l152c6.h"
#include"stdbool.h"
#include"stdint.h"
#define _5NOPS asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop")//用于I2C讀寫延時
/******************************************************************************************************
* 名 稱:void delay_10ms(uint8_t x_ms)
* 功 能:延時10ms
* 入口參數:無
* 出口參數:無
* 說 明:
* 范 例:無
******************************************************************************************************/
void delay_100ms(void)
{
uint8_t i,j;
for(i=0;i<255;i++)//2*255個指令周期
for(j=0;j<255;j++);//2*255個指令周期
// delay_10ms共消耗 x_ms*2*255+2*x_ms個指令周期
// 255*2*255+2*255=130610us=130ms
// 此延時函數,延時時間為130ms
// 16M/8/2=1M 一個指令周期為1us
}
/******************************************************************************************************
* 名 稱: uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)
* 功 能:從I2C從設備中讀取一字節的數據
* 入口參數:address:讀取數據的寄存器地址
* 出口參數:返回一個從I2C從設備指定地址讀到的數據
* 說 明:
* 范 例:無
******************************************************************************************************/
uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)
{
volatile uint8_t t;
//----------I2C起始信號--------------
I2C1_CR2_START=1;//產生一個起始條件
while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標志位
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
//-------發送寫I2C從器件地址---------
I2C1_DR=0xA0;//發送從設備地址
while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標志位
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標志位
// 0: Data bytes received
// 1: Data bytes transmitted
//-----寫I2C從器件寄存器地址--------
I2C1_DR=address;
while(!(I2C1_SR1_BTF==1));//等待地址發送完成
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
//--------I2C重復起始信號-----------
I2C1_CR2_START=1;//重復產生一個起始條件
while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標志位
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
//-------發送讀I2C從器件地址---------
I2C1_DR=0xA1;//發送從設備地址
while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標志位
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
if(I2C1_SR3_TRA==1)return 1;//讀SR3寄存器,清除ADDR標志位
while(!(I2C1_SR1_RXNE==1));//等待地址發送完成
//-------------停止信號-------------
I2C1_CR2_STOP=1;
//-------------讀取數據-------------
t=I2C1_DR;
return t;
}
/******************************************************************************************************
* 名 稱:void I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)
* 功 能:寫入一字節的數據到I2C設備中
* 入口參數:address:寫入的數據存儲地址 dat:待寫入的數據
* 出口參數:無
* 說 明: 通過MSTM8L硬件寫入I2C設備一個字節的數據
* 范 例:無
******************************************************************************************************/
uint8_t I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)
{
volatile uint8_t t;
//----------I2C起始信號--------------
I2C1_CR2_START=1;//產生一個起始條件
while(!(I2C1_SR1_SB==1));
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
I2C1_DR=0xA0;
//--------寫I2C從器件地址-----------
while(!(I2C1_SR1_ADDR==1));
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標志位
//-----寫I2C從器件寄存器地址--------
while(!(I2C1_SR1_TXE==1));
I2C1_DR=address;
//-------寫I2C數據到寄存器中--------
while(!(I2C1_SR1_TXE==1));
I2C1_DR=dat;
while(!(I2C1_SR1_TXE==1));
while(!(I2C1_SR1_BTF==1));
_5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時
//-------------停止信號-------------
I2C1_CR2_STOP=1;
return 0;
}
/******************************************************************************************************
* 名 稱: IIC_init()
* 功 能:初始化IIC
* 入口參數:無
* 出口參數:無
* 說 明:PC0--SDA PC1--SCL
* 范 例:無
******************************************************************************************************/
void I2C_Init(void)
{
//----打開IIC外設時鐘----
CLK_PCKENR1_PCKEN13=1;//
I2C1_CR1_PE=0;
//----I2C輸入時鐘頻率選擇----
I2C1_FREQR_FREQ=0x02;//2MHz
/* The allowed range is between 1 MHz and 16 MHz
000000: not allowed
000001: 1 MHz
000010: 2 MHz
...
010000: 16 MHz */
//----配置時鐘控制寄存器----
I2C1_CCRH_F_S=0; //Standard mode I2C
I2C1_CCRL=10; //SCK低電平時間配置
//I2C的SCK時鐘設置為100KHz,則SCK周期為10us
//因為I2C1_FREQR_FREQ=0x02,即I2C輸入時鐘頻率為2M,周期為0.5us
//CCR=10時,SCK的低電平時間為tlow=10*0.5us=5us,SCk高電平時間為thigh=10*0.5us=5us
//所以CCR=10時,SCK輸出頻率為100KHz
//----配置上升時間寄存器----
I2C1_TRISER_TRISE=3;//in standard mode, the maximum allowed SCL rise time is 1000 ns.
//1 us / 0.5 us = 2 + 1
I2C1_CR1_PE=1;//
}
void main(void)
{
static uint8_t tmp=0;
I2C_Init();
// asm("rim"); //enable interrupts
I2C_WriteOneByteDataToSlave(0x02,0x84);
delay_100ms();
tmp=I2C_ReadOneByteDataFromSlave(0x02);
asm("nop");
while(1)
{
asm("wfi");
}
}
復制代碼
作者:
Blackboy
時間:
2020-5-15 08:55
樓主你好,最近也用到這個8L的單片機,用到了I2C,參考你的代碼復制,在調試的時候就一直卡在這while(!(I2C1_SR1_SB==1)); 示波器上是有SCL時鐘輸出的,請問下樓主有遇到這樣的情況嗎
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1