int main(void)
{
I2C_PortInit();
/* 초기 쓰레기값 읽어주기 */
AT24LCXX_Init();
for(uint32_t i=0; i<260; i++){
tAT24CXX(i);
}
}
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usr_softI2C.h"
#include "usr_uart.h"
#include "string.h"
/* Defines -------------------------------------------------------------------*/
#define I2C_PORT GPIOB
#define I2C_SCL GPIO_Pin_6
#define I2C_SDA GPIO_Pin_7
#define AT24CXX_BLOCKA_ADDR 0xA0//1010 0000
#define AT24CXX_BLOCKB_ADDR 0xA8//1010 1000
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void I2C_PortInit(void)
{
/* I2C1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
void I2C_WRITE(unsigned char dat)
{
u8 bit_cnt, tmp;
u8 bit_value;
for(bit_cnt=0; bit_cnt<8; bit_cnt++)
{
tmp = (dat << bit_cnt) & 0x80;
bit_value = (tmp >> 7) & 0x01;
if(bit_value == 1)
GPIO_SetBits(I2C_PORT,I2C_SDA);
else
GPIO_ResetBits(I2C_PORT,I2C_SDA);
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SCL);
delay_us(5);
GPIO_ResetBits(I2C_PORT,I2C_SCL);
delay_us(5);
}
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
void I2C_START(void)
{
GPIO_SetBits(I2C_PORT,I2C_SCL);//SCL=1;
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SDA);//SDA=1;
delay_us(5);
GPIO_ResetBits(I2C_PORT,I2C_SDA);//SDA=0;
delay_us(5);
GPIO_ResetBits(I2C_PORT,I2C_SCL);//SCL=0;
delay_us(5);
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
void I2C_STOP(void)
{
GPIO_ResetBits(I2C_PORT,I2C_SDA);
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SCL);
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SDA);
delay_us(7);
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
void I2C_SEND_ACK(u8 bit_value)
{
if(bit_value == 1)
GPIO_SetBits(I2C_PORT,I2C_SDA);
else
GPIO_ResetBits(I2C_PORT,I2C_SDA);
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SCL);
delay_us(5);
GPIO_ResetBits(I2C_PORT,I2C_SCL);
delay_us(5);
GPIO_SetBits(I2C_PORT,I2C_SDA);
delay_us(5);
}
/*******************************************************************************
* Function Name :
* Parameters :
* Return : none
* Description :
*******************************************************************************/
uint8_t I2C_READ(void)
{
uint8_t i_byte, n;
GPIO_SetBits(I2C_PORT,I2C_SDA);
delay_us(5);
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
for(n=0; n<8; n++)
{
GPIO_SetBits(I2C_PORT,I2C_SCL);
delay_us(5);
if (GPIO_ReadInputDataBit(I2C_PORT,I2C_SDA)){
i_byte = (i_byte << 1) | 0x01; // msbit first
}
else{
i_byte = i_byte << 1;
}
GPIO_ResetBits(I2C_PORT,I2C_SCL);
delay_us(5);
}
/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
return(i_byte);
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void AT24CXX_Write(uint8_t Address, uint16_t addr, uint8_t* pBuffer, uint16_t NumByteToWrite)
{
uint16_t unNum = 0;
for(uint8_t i=0; i <= NumByteToWrite/128; i++)
{
I2C_START();
I2C_WRITE(Address);
I2C_SEND_ACK(0);
I2C_WRITE((addr >> 8) & 0xff); // high byte of memory address
I2C_SEND_ACK(0);
I2C_WRITE(addr & 0xff); // low byte of mem address
I2C_SEND_ACK(0);
if(i < NumByteToWrite/128){
unNum = 128;
}
else{
unNum = NumByteToWrite%128;
}
/* While there is data to be written */
while(unNum--){
/* Send the current byte */
I2C_WRITE(*pBuffer);
/* Point to the next byte to be written */
pBuffer++;
I2C_SEND_ACK(0);
}
I2C_STOP();
addr += 128;
delay_ms(20);
}
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void AT24CXX_Read(uint8_t Address, uint16_t addr, uint8_t* pBuffer, uint16_t NumByteToWrite)
{
I2C_START();
I2C_WRITE(Address);
I2C_SEND_ACK(0);
I2C_WRITE((addr >> 8) & 0xff);
I2C_SEND_ACK(0);
I2C_WRITE(addr & 0xff);
I2C_SEND_ACK(0);
I2C_START();
I2C_WRITE(Address | (1 << 0));
I2C_SEND_ACK(0);
while(NumByteToWrite--)
{
*pBuffer = I2C_READ();
pBuffer++;
if(NumByteToWrite){
I2C_SEND_ACK(0);
}
else{
I2C_SEND_ACK(1);
}
}
I2C_STOP();
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void AT24LCXX_1ByteWrite(uint8_t dev_adr, uint16_t mem_adr, uint8_t a_chDat)
{
I2C_START();
I2C_WRITE(AT24CXX_BLOCKA_ADDR | (dev_adr << 1));
I2C_SEND_ACK(0);
I2C_WRITE((mem_adr >> 8) & 0xff); // high byte of memory address
I2C_SEND_ACK(0);
I2C_WRITE(mem_adr & 0xff); // low byte of mem address
I2C_SEND_ACK(0);
I2C_WRITE(a_chDat); // and finally the data
I2C_SEND_ACK(0);
I2C_STOP();
delay_ms(25); // allow for the programming of the eeprom
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
uint8_t AT24LCXX_1ByteRead(uint8_t dev_adr, uint16_t mem_adr)
{
uint8_t Dat;
I2C_START();
I2C_WRITE(AT24CXX_BLOCKA_ADDR | (dev_adr << 1));
I2C_SEND_ACK(0);
I2C_WRITE((mem_adr >> 8) & 0xff);
I2C_SEND_ACK(0);
I2C_WRITE(mem_adr & 0xff);
I2C_SEND_ACK(0);
I2C_START(); // no intermediate stop
I2C_WRITE(0xa1 | (dev_adr << 1)); // read operation
I2C_SEND_ACK(0);
Dat = I2C_READ();
I2C_SEND_ACK(1);
I2C_STOP();
return Dat;
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
uint8_t AT24LCXX_Init(void)
{
uint8_t ch;
/* Dummy */
ch = AT24LCXX_1ByteRead(0x00, 0x00);
return ch;
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void tAT24CXX(uint32_t addr)
{
uint32_t mem_adr;
uint8_t dat[512], ch;
uint16_t n;
mem_adr = addr *512;
UART2_printf("addr %d, mem_adr %d \r\n", addr, mem_adr);
memset(dat, 0, sizeof(dat));
if(mem_adr < 0xFFFF){
AT24CXX_Read(AT24CXX_BLOCKA_ADDR, mem_adr, dat, 512);
}
else{
AT24CXX_Read(AT24CXX_BLOCKB_ADDR, mem_adr, dat, 512);
}
printData("dat b", dat, 512);
if(dat[0] != 0x32)
{
dat[0] = 0x32;
dat[1] = (addr >> 8) & 0xff;
dat[2] = (addr & 0xff);
UART2_printf("dat[1] %d, dat[2] %d \r\n", dat[1], dat[2]);
for(n=3; n<512; n++){
dat[n] = (uint8_t)(n%255);
}
if(mem_adr < 0xFFFF){
AT24CXX_Write(AT24CXX_BLOCKA_ADDR, mem_adr, dat, 512);
}
else{
AT24CXX_Write(AT24CXX_BLOCKB_ADDR, mem_adr, dat, 512);
}
printData("dat f", dat, 512);
}
delay_ms(1000);
}
/*******************************************************************************
* Function Name :
* Description :
* Parameters : None
* Return : None
*******************************************************************************/
void tAT24CXX_1Byte(void)
{
long mem_adr;
uint8_t dat[512];
uint16_t n;
AT24LCXX_Init();
mem_adr=0x0000;
UART2_printf("dat b\r\n");
for(n=0; n<512; n++)
{
dat[n] = AT24LCXX_1ByteRead(0x00, mem_adr);
UART2_printf("%x", dat[n]);
++mem_adr;
}
UART2_printf("\r\n");
if(dat[0] != 0x31)
{
UART2_printf("dat f\r\n");
mem_adr=0x0000;
dat[0] = 0x31;
AT24LCXX_1ByteWrite(0x00, mem_adr, dat[0]);
mem_adr=0x0001;
for(n=1; n<512; n++)
{
dat[n] = (uint8_t)(n%255);
UART2_printf("%x", dat[n]);
AT24LCXX_1ByteWrite(0x00, mem_adr, dat[n]);
++mem_adr;
}
UART2_printf("\r\n");
UART2_printf("Write\r\n");
}
delay_ms(1500);
}
'초보의 아웅다웅 설계하기 > STM32' 카테고리의 다른 글
STM32F Sleep Mode에서 Uart로 Wakeup하기 (0) | 2018.12.06 |
---|---|
SoftUart Only TX (2) | 2018.10.22 |
OLED QG-2864KSWLG01 내부 펌프 초기 코드 (0) | 2018.09.01 |
Partial Erase Done (areas with no algorithms skipped!) 에러 발생 (0) | 2018.08.17 |
Keil, IAR고정위치에 바이너리 라이팅하기 (0) | 2018.08.17 |