Всем привет. Столкнулся с проблемой, может кто уже сталкивался с подобным, или может хоть подскажите в какую сторону смотреть. Дело вот в чём: простая тестовая программа, передранная целиком и полностью из интернета(упростил в процессе поиска глюка, потом по функциям всё разложу) передаёт число 0х44 в устройство с адресом 0х12 по I2C.
Настроил тактирование контроллера, порты и сам интерфейс. Бросаю стартовый бит, нормально. Бросаю адрес, отлично. Отсылаю байт данных, а на выходе идёт 18 бит, то бишь 2 байта. В чём моя ошибка? Контроллер stm32f103C8T6. Среда - coocox.
Да там ещё была загвоздка, вместо проверки на окончание передачи адреса и самого байта пришлось ставить задержки. Я знаю что это колхоз, но не смог найти какой флаг проверять. Если кто подскажет буду очень рад.
Привожу код и скрин с анализатора.
Раздел: STM32
Настроил тактирование контроллера, порты и сам интерфейс. Бросаю стартовый бит, нормально. Бросаю адрес, отлично. Отсылаю байт данных, а на выходе идёт 18 бит, то бишь 2 байта. В чём моя ошибка? Контроллер stm32f103C8T6. Среда - coocox.
Да там ещё была загвоздка, вместо проверки на окончание передачи адреса и самого байта пришлось ставить задержки. Я знаю что это колхоз, но не смог найти какой флаг проверять. Если кто подскажет буду очень рад.
Привожу код и скрин с анализатора.
#include "stm32f10x_gpio.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_rcc.h"
//********************************************************************************
unsigned char InitClk()
{
unsigned long int TimeOut = 10000;
//Запустить HSE
RCC->CR |= RCC_CR_HSEON; //Включить генератор HSE
while((RCC->CR & RCC_CR_HSERDY)==0) //Ожидание готовности HSE
if(TimeOut) TimeOut--;
if(TimeOut==0) return 1; //Ошибка!!! Генератор HSE не запустился
RCC->CR |= RCC_CR_CSSON; //Разрешить работу системы защиты сбоя HSE
//Подключить систему к HSE
RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
RCC->CFGR |= RCC_CFGR_SW_HSE; //Выбрать источником тактового сигнала HSE
//Настроить делитель для AHB
RCC->CFGR &= ~RCC_CFGR_HPRE; //Очистка битов предделителя "AHB Prescaler"
RCC->CFGR |= RCC_CFGR_HPRE_DIV2; //Установить "AHB Prescaler" равным 2
return 0; //Все ok, работаем от HSE
}
//********************************************************************************
//Function: обработчик прерывания при сбое генератора HSE //
//********************************************************************************
void NMI_Handler(void)
{
//Сбросить флаг системы контроля сбоя HSE
if (RCC->CIR & RCC_CIR_CSSF) RCC->CIR |= RCC_CIR_CSSC;
//Если контроллер здесь, значит HSE не работает
//Что-то можно предпринять: перезапустить генератор, дать сигнал аврии и т.п.
}
//********************************************************************************
GPIO_InitTypeDef gpio;
I2C_InitTypeDef i2c;
/*******************************************************************/
void init_I2C1(void)
{//Конфигурация I2C и портов под него
GPIO_PinRemapConfig(GPIO_Remap_I2C1, DISABLE);
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
I2C_DeInit (I2C1);
GPIO_DeInit(GPIOB);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 50000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
int main(void)
{
InitClk();
init_I2C1();
uint8_t transmissionDirection = I2C_Direction_Transmitter;
uint8_t slaveAddress = 0x12;
// Генерируем старт - тут все понятно )
I2C_GenerateSTART(I2C1, ENABLE);
// Ждем пока взлетит нужный флаг
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, slaveAddress, transmissionDirection);
uint8_t i;
for(i=0;i<0x50;i++);//Задержка на время адреса
uint8_t data = 0x44;
I2C_SendData(I2C1, data);
for(i=0;i<0x70;i++);//Задержка на время данных
I2C_GenerateSTOP(I2C1, ENABLE);
while(1){ }
}
Раздел: STM32