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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STM8L的I2C基本讀寫方法詳解 含例程

[復制鏈接]
跳轉到指定樓層
樓主
ID:140343 發表于 2016-10-10 00:52 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
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中文文檔中,對此描述如下.


  1. /*硬件連接*/

  2. // PC0<--->SDA   PC1---->SCL

  3. /****************************************************************************************

  4. *開發環境:IAR for stm8 v6.5.3

  5. *硬件平臺:STM8L-DISCOVERY

  6. *功能說明:通過硬件I2C等待的方法,實現對24C02寄存器的讀寫,借助IAR軟件的調試功能,查看變量的數值

  7. *作    者:茗風

  8. ****************************************************************************************/

  9. #include"iostm8l152c6.h"

  10. #include"stdbool.h"

  11. #include"stdint.h"


  12. #define  _5NOPS     asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop")//用于I2C讀寫延時

  13. /******************************************************************************************************

  14. *  名    稱:void delay_10ms(uint8_t x_ms)

  15. *  功    能:延時10ms

  16. *  入口參數:無

  17. *  出口參數:無

  18. *  說    明:

  19. *  范    例:無

  20. ******************************************************************************************************/

  21. void delay_100ms(void)

  22. {

  23.   uint8_t i,j;

  24.   for(i=0;i<255;i++)//2*255個指令周期

  25.     for(j=0;j<255;j++);//2*255個指令周期

  26.   // delay_10ms共消耗 x_ms*2*255+2*x_ms個指令周期  

  27.   // 255*2*255+2*255=130610us=130ms

  28.   // 此延時函數,延時時間為130ms

  29.   // 16M/8/2=1M 一個指令周期為1us

  30. }

  31. /******************************************************************************************************

  32. * 名 稱: uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)

  33. * 功 能:從I2C從設備中讀取一字節的數據

  34. * 入口參數:address:讀取數據的寄存器地址

  35. * 出口參數:返回一個從I2C從設備指定地址讀到的數據

  36. * 說 明:

  37. * 范 例:無

  38. ******************************************************************************************************/

  39. uint8_t I2C_ReadOneByteDataFromSlave(uint8_t address)

  40. {

  41.   volatile uint8_t t;

  42.   

  43.   //----------I2C起始信號--------------

  44.   I2C1_CR2_START=1;//產生一個起始條件

  45.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標志位

  46.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  47.   

  48.   //-------發送寫I2C從器件地址---------

  49.   I2C1_DR=0xA0;//發送從設備地址

  50.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標志位

  51.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  52.   if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標志位

  53.   //  0: Data bytes received

  54.   //  1: Data bytes transmitted

  55.   

  56.   //-----寫I2C從器件寄存器地址--------

  57.   I2C1_DR=address;

  58.   while(!(I2C1_SR1_BTF==1));//等待地址發送完成

  59.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  60.   

  61.   //--------I2C重復起始信號-----------

  62.   I2C1_CR2_START=1;//重復產生一個起始條件

  63.   while(!(I2C1_SR1_SB==1));//讀SR1寄存器,清除SB標志位

  64.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  65.   

  66.   //-------發送讀I2C從器件地址---------

  67.   I2C1_DR=0xA1;//發送從設備地址

  68.   while(!(I2C1_SR1_ADDR==1));//讀SR1寄存器,清除ADDR標志位

  69.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  70.   if(I2C1_SR3_TRA==1)return 1;//讀SR3寄存器,清除ADDR標志位

  71.   while(!(I2C1_SR1_RXNE==1));//等待地址發送完成

  72.   

  73.   //-------------停止信號-------------

  74.   I2C1_CR2_STOP=1;

  75.   

  76.   //-------------讀取數據-------------

  77.   t=I2C1_DR;

  78.   

  79.   return t;

  80. }

  81. /******************************************************************************************************

  82. * 名 稱:void I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)

  83. * 功 能:寫入一字節的數據到I2C設備中

  84. * 入口參數:address:寫入的數據存儲地址    dat:待寫入的數據

  85. * 出口參數:無

  86. * 說 明: 通過MSTM8L硬件寫入I2C設備一個字節的數據

  87. * 范 例:無

  88. ******************************************************************************************************/

  89. uint8_t I2C_WriteOneByteDataToSlave(uint8_t address,uint8_t dat)

  90. {

  91.   volatile uint8_t t;

  92.   //----------I2C起始信號--------------

  93.   I2C1_CR2_START=1;//產生一個起始條件

  94.   while(!(I2C1_SR1_SB==1));

  95.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  96.   I2C1_DR=0xA0;

  97.   

  98.   //--------寫I2C從器件地址-----------

  99.   while(!(I2C1_SR1_ADDR==1));

  100.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  101.   if(I2C1_SR3_TRA==0)return 1;//讀SR3寄存器,清除ADDR標志位

  102.   

  103.   //-----寫I2C從器件寄存器地址--------

  104.   while(!(I2C1_SR1_TXE==1));

  105.   I2C1_DR=address;

  106.   

  107.   //-------寫I2C數據到寄存器中--------

  108.   while(!(I2C1_SR1_TXE==1));

  109.   I2C1_DR=dat;

  110.   while(!(I2C1_SR1_TXE==1));

  111.   while(!(I2C1_SR1_BTF==1));

  112.   _5NOPS;//根據數據手冊,檢測到標志位后,需插入5個NOP進行延時

  113.   

  114.   //-------------停止信號-------------

  115.   I2C1_CR2_STOP=1;

  116.   return 0;

  117. }


  118. /******************************************************************************************************

  119. * 名 稱: IIC_init()

  120. * 功 能:初始化IIC

  121. * 入口參數:無

  122. * 出口參數:無

  123. * 說 明:PC0--SDA   PC1--SCL

  124. * 范 例:無

  125. ******************************************************************************************************/

  126. void I2C_Init(void)

  127. {

  128.   //----打開IIC外設時鐘----

  129.   CLK_PCKENR1_PCKEN13=1;//

  130.   I2C1_CR1_PE=0;

  131.   

  132.   //----I2C輸入時鐘頻率選擇----

  133.   I2C1_FREQR_FREQ=0x02;//2MHz

  134.   /*  The allowed range is between 1 MHz and 16 MHz

  135.   000000: not allowed

  136.   000001: 1 MHz

  137.   000010: 2 MHz

  138.   ...

  139.   010000: 16 MHz                                 */

  140.   

  141.   //----配置時鐘控制寄存器----

  142.   I2C1_CCRH_F_S=0; //Standard mode I2C

  143.   I2C1_CCRL=10;    //SCK低電平時間配置

  144.   //I2C的SCK時鐘設置為100KHz,則SCK周期為10us

  145.   //因為I2C1_FREQR_FREQ=0x02,即I2C輸入時鐘頻率為2M,周期為0.5us

  146.   //CCR=10時,SCK的低電平時間為tlow=10*0.5us=5us,SCk高電平時間為thigh=10*0.5us=5us

  147.   //所以CCR=10時,SCK輸出頻率為100KHz

  148.   

  149.   //----配置上升時間寄存器----

  150.   I2C1_TRISER_TRISE=3;//in standard mode, the maximum allowed SCL rise time is 1000 ns.

  151.   //1 us / 0.5 us = 2 + 1


  152.   I2C1_CR1_PE=1;//

  153.   

  154. }


  155. void main(void)

  156. {

  157.   static uint8_t tmp=0;

  158.   I2C_Init();

  159. //  asm("rim");               //enable interrupts

  160.   I2C_WriteOneByteDataToSlave(0x02,0x84);

  161.   delay_100ms();

  162.   tmp=I2C_ReadOneByteDataFromSlave(0x02);

  163.   asm("nop");

  164.   while(1)

  165.   {

  166.     asm("wfi");

  167.   }

  168. }
復制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:161571 發表于 2020-5-15 08:55 | 只看該作者
樓主你好,最近也用到這個8L的單片機,用到了I2C,參考你的代碼復制,在調試的時候就一直卡在這while(!(I2C1_SR1_SB==1)); 示波器上是有SCL時鐘輸出的,請問下樓主有遇到這樣的情況嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美不卡一区二区三区 | 精品国产乱码久久久久久88av | 亚洲国产午夜 | 影音先锋成人资源 | 一区二区三区国产 | 中文字幕在线观看 | 精品国产一区二区 | 久久国产日韩 | 91中文字幕| 国产不卡一区 | 成人午夜网站 | 精品国产18久久久久久二百 | 色本道| 成人免费看电影 | 日韩欧美视频 | 欧美日韩久 | 日本高清精品 | 久久成人免费 | 成人毛片视频免费 | 夫妻午夜影院 | 国产探花在线精品一区二区 | 91av在线免费观看 | 精品亚洲永久免费精品 | 青青草原精品99久久精品66 | 欧美日韩一区二区在线观看 | 国产毛片久久久 | 国产区在线观看 | 激情av免费看| 在线欧美视频 | 99成人在线视频 | 高清久久| 国产精品久久久久久久久大全 | 国产精品视频一区二区三区四区国 | 蜜桃视频在线观看免费视频网站www | 日韩精品一二三区 | 能免费看的av| 国产精品毛片一区二区在线看 | 亚洲精品自在在线观看 | 日韩在线电影 | 精品视频在线一区 | 中国美女一级黄色片 |