The following is the .h file:
PA1 is defined as SDA and PA2 is defined as SCL
#ifndef __I2C_H
#define __I2C_H
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "tim1.h"
#include "uart.h"
#include #include #define SCL PA_ODR_ODR2 #define SDA PA_ODR_ODR1 #define SDAM PA_IDR_IDR1 #define SET_SCL_OUT() {PA_DDR_DDR2=1; PA_CR1_C12 = 1; PA_CR2_C22 = 0;} #define SET_SDA_OUT() {PA_DDR_DDR1=1; PA_CR1_C11 = 1; PA_CR2_C21 = 0;} #define SET_SDA_IN() {PA_DDR_DDR1=0; PA_CR1_C11 = 0; PA_CR2_C21 = 0;} void IIC_Init(void); void Delay_us(u8 z); void I2C_Start(void); void I2C_Stop(void); void IIC_Ack(void); void IIC_NAck(void); uint8_t IIC_Wait_Ack(void); void IIC_Send_Byte(uint8_t txd); uint8_t IIC_Read_Byte(uint8_t ack); void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data); void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num); #endif The following is the .c file: #include "I2C.h" //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void IIC_Init(void) { SET_SCL_OUT(); SET_SDA_OUT(); SCL = 1; SDA = 1; } //-------------------------------------------------------------- // Prototype : void Delay_5us(void) // Description: Delay of about 5us //-------------------------------------------------------------- void Delay_us(u8 z) { //u8 i; //fcpu 8MHz //for (i=50; i>0; i--); while(z--) { nop();nop();nop();nop(); } } //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start(void) { // SDA 1->0 while SCL High //During the high level of SCL, a falling edge appears on SDA to indicate the start signal SET_SDA_OUT(); SDA = 1; //The data line is kept high first, and the start signal needs the falling edge of the port Delay_us(4); SCL = 1; //The clock line remains high Delay_us(40); //There is a delay of about 5us, which depends on the device SDA = 0; //The data line is pulled low and a falling edge appears Delay_us(4); //Delay for a short while to ensure a reliable falling edge SCL = 0; //Pull the clock line low to ensure that the data line is allowed to change next } //-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop(void) { // SDA 0->1 while SCL High //During the SCL high level period, SDA generates a rising edge to indicate stop SET_SDA_OUT(); SCL = 0; Delay_us(2); SDA = 0; // Ensure the data line is low level Delay_us(40); SCL = 1; //First ensure that the clock line is high Delay_us(10); //Delay to get a reliable level signal SDA = 1; // Rising edge on data line Delay_us(40); //Delay to ensure a reliable high level } //Response function void IIC_Ack(void) { //The data line remains at a low level, and a rising edge on the clock line indicates a response SET_SDA_OUT(); Delay_us(10); SDA = 0; Delay_us(10); SCL = 0; Delay_us(40); SCL = 1; Delay_us(40); //After the response is completed, pull the clock line low to allow data modification SCL = 0; } //Non-response void IIC_NAck(void) { //Non-response is the opposite of response. The difference is that the data line remains at a high level. SET_SDA_OUT(); Delay_us(10); SDA = 1; Delay_us(10); SCL = 0; Delay_us(40); SCL = 1; Delay_us(40); //Finally, pull the clock line low to allow data to change SCL = 0; } //Wait for response uint8_t IIC_Wait_Ack(void) //0 means there is a response, 1 means there is no response { //Response waiting count uint8_t ackTime = 0; //First set the data line to input mode. This program does not reflect this. If there is a response, a falling edge will appear. SCL = 0; SET_SDA_OUT(); Delay_us(10); SDA = 1;// Delay_us(30); SET_SDA_IN(); //Switch to input mode //Pull the clock line high SCL = 1; Delay_us(30); //Wait for the data line to pull low for response while(SDAM){ //If it is not pulled low within this time ackTime ++; if(ackTime > 250) { // Consider it a non-response stop signal I2C_Stop(); return 1; } } SCL = 0; return 0 ; } void IIC_Send_Byte(uint8_t txd) { //Define a counting variable uint8_t i; SET_SDA_OUT(); //Pull the clock line low to allow data to change // SCL = 0; //Send data bit by bit for(i = 0;i < 8; i ++) { Delay_us(2); if((txd&0x80)>>7) //0x80 1000 0000 SDA=1; else SDA=0; txd<<=1; Delay_us(20); SCL=1; Delay_us(20); SCL=0; Delay_us(20); } } //The return value is the received data //Parameter is whether to respond 1 is response 0 is not response uint8_t IIC_Read_Byte(uint8_t ack) { //Define the counting variable uint8_t i = 0; //Define the receiving variable uint8_t receive = 0; //At this time, the data line mode should be switched to input mode. This is not reflected in this program. SET_SDA_IN(); //Switch to input mode for(i = 0;i < 8; i ++) { Delay_us(50); SCL = 0; Delay_us(50); //Pull the clock line high to read the data to ensure that the other party's data does not change SCL = 1; // Add a delay to ensure the level is reliable // Delay_us(5); //First left shift the receiving variable to prevent the variable from being changed at the end of the loop receive<<=1; //Judge the data line level if(SDAM) { //If the level is high, the receiving variable is incremented, and if the level is low, it does not change but only shifts left, which ensures that the bit is 0 receive++; } // Delay for a short while to ensure a reliable level // Delay_us(1); //Pull the clock line low to allow the next bit of data to change //SCL = 0; } Delay_us(50); SCL = 0; // if(!ack) // { //If no response is needed, a non-response signal is given and no further progress is made // IIC_NAck(); // } // else // { //If a response is needed, give a response // IIC_Ack(); // } return receive; } void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data) { //Start signal I2C_Start(); //Send device address IIC_Send_Byte(DeciveAddr); //Wait for response IIC_Wait_Ack(); //Send data address IIC_Send_Byte(DataAddr); //Wait for response IIC_Wait_Ack(); //send data IIC_Send_Byte(Data); //Wait for response IIC_Wait_Ack(); //End signal I2C_Stop(); } //Read data //Parameter 1 device address //Parameter 2 data address //Parameter three receives data storage //Parameter 4 receiving length // void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num) { //Define the counting variable uint8_t i; //Start signal I2C_Start(); //Send device address IIC_Send_Byte(DeciveAddr); //Wait for response IIC_Wait_Ack(); //Send data address IIC_Send_Byte(DataAddr); //Wait for response IIC_Wait_Ack(); //Start signal I2C_Start(); //Send device address read mode IIC_Send_Byte(DeciveAddr + 1); //Wait for response IIC_Wait_Ack(); //Read data for(i = 0;i < (num-1);i ++) { //The first num-1 bits of data need to be answered because they need to continue reading *ReciveData= IIC_Read_Byte(1); ReciveData++; } //The last bit of data does not need to be responded to because it does not need to be read *ReciveData = IIC_Read_Byte(0); //Stop signal I2C_Stop(); } Note: I2C communication requires an external pull-up resistor!
Previous article:STM8S AWU low power mode
Next article:STM8S TM1650 chip control program
Recommended ReadingLatest update time:2024-11-23 10:38
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- How to judge the positive and negative turning angle in PID vehicle lateral control
- HT6221-2 decodes into standard key values
- Can anyone share a cracked version of ATLIUM? I recently changed my computer and my previous AD9 can no longer be cracked.
- Li Zhipeng, Lu Xuanjun and Wang Peng: Ultrasonic obstacle avoidance Bluetooth car
- [GD32L233C-START Review] 2. Create a new project step by step
- Zigbee network data transmission method
- What exactly is op amp noise?
- PICO Solar System Clock
- Has anyone made a radio transmitter and receiver recently?
- ST MEMS device resource library (official ST information, practical information)