Search the Community
Showing results for tags 'I2C'.
Found 29 results
-
Здравствуйте! Пишу программу на C++ для управления LCD (HD44780) по I2C через модуль расширения портов ввода/вывода PCF8574AT. void LCD_I2C::readBF() { transmitByte(0b00001110); //transmits E, RW set to HIGH and RS, set to LOW _delay_ms(5); transmitByte(0b00001010); //transmits E, RS set to LOW and RW set to HIGH _delay_ms(5); initRestart(); transmitAddrRW(0b01111111); //sends PCF8574AT address + SLA+R do { receiveDataAck(); PORTA = storage; } while((storage & (1 << BF)) != 0); //wait until BF is 0 initRestart(); transmitAddrRW(0b01111110); } Метод void transmitByte(uint8_t data) после инициализации состояния "Старт" и отправки адреса устройства + SLA+W отправляет байт данных по TWI с ожиданием бита подтверждения (команды работают верно, проверял по регистру статуса TWI - 0x08, 0x10 и 0x24). Метод void transmitAddrRW(uint8_t address) отправляет соответственно SLA+W/R + адрес устройства (команда работает также верно). Нареканий к работе TWI у меня нет, т.к. недавно с его помощью успешно запустил часы DS1307 с интеграцией LCD. После передачи запроса на чтение флага занятости инициализируется состояние "ПОВСТАРТ", отправляется адрес устройства + SLA+R, далее идет цикл - запрос байта данных (состояние выводов PCF8574AT) с отправкой бита подтверждения uint8_t receiveDataAck() (команды работают также верно, возвращает storage = TWDR) и вывод storage на порт А микроконтроллера (там установлены светодиоды). Чтение регистра данных TWDR после принятия байта данных (receiveDataAck()) дает следующий результат - 0b00000010 - установлен только бит RW микросхемы. Таким образом, флаг занятости BF = DB7 = 7й бит оказывается сразу же сброшенным, происходит мгновенный выход из цикла - контроллер дисплея не успевает скушать информацию, и инициализация не выполняется (неудачную инициализацию определяю по отсутствию курсора). Ожидалось, что флаг занятости будет установлен в единицу и произойдет несколько итераций перед выходом из цикла. При замене метода ожидания сброса флага занятости BF на программную задержку в 250 мс везде, где это требует datasheet - инициализация происходит успешно (появляется курсор, как и должно быть). Вопрос: что можно сделать, чтобы вместо _delay_ms(250) использовать readBF(), т.к. этот путь мне кажется более верным (уж очень не хочется использовать задержку .__.)? Возможно, проблема в микросхеме, которая неверно выдает информацию при чтении? (Имеется вторая микросхема, она вообще не работает:D) З.Ы. На фото виден результат чтения флага BF и Adress Counter - установлен только бит RW. З.Ы.Ы Кому интересно - вот функция main(). Повторюсь - проблема только в методе readBF(): void LCD_I2C::init() { setBitRate(20000); initStart(); transmitAddrRW(0b01111110); //send PCF8574AT address + SLA+W _delay_ms(60); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(20); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(5); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(5); sendInstruction(0b00100000); //function set 4-bit operation readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00100000); //function set 4-bit operation, 2 lines, 5x8 dots sendInstruction(0b10000000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display off, cursor off, blinking off sendInstruction(0b10000000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display clear sendInstruction(0b00010000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //entry mode set increment, display shift off sendInstruction(0b01100000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display on, cursor off, blinking off sendInstruction(0b11100000); readBF();/ }
-
Доброго времени суток! В целом, имеется опыт разработки малых устройств, что-то понимаю, в общем, старательно читаю даташиты, даже понимаю их, но на звание серьёзного инженера (пока что) не претендую. Я пытаюсь использовать I2C на 8-битном PIC16F18326. Сижу в даташитах. Всё понимаю, всё делаю, на мой неопытный взгляд, правильно. Даже копирую полностью рабочие примеры (я даже купил такой же микроконтроллер, как в примере, скопировал код, контролируя, что он делает. Но всё равно не работает - SCL/SDA на 5в и всё тут). Так вот: PIC16F18326 on breadboard (прошу прощения, я хз как это по-русски) на внутреннем 32мгц кристалле. Чип пашет, без проблем моргаю LEDкой. Ну, думаю, щас быстренько подниму I2C. В итоге SCL SDA сидят на 5в без движения. Я использую LED для отладки. Судя по LED, код заloopливается в месте, где проверяется while PIR1bits.SSP1IF==0. Я уже везде был, кучу форумов перерыл. Уже попробовал всё, что мог представить. Я довольно новый в мире PIC, хотел попробовать их, а они ужасно сопротивляются. Уже 2 недели долблюсь безуспешно. Подтяжки 10к, проблем с ними никогда не было. Собственно, вот код (я уже там попробовал повыключать ADC, вычитал про баг, что сначала I2C пины надо делать OUTPUT LOW, а потом уже INPUT из-за бага MSSP, но ничего не помогло). // PIC16F18326 Configuration Bit Settings // 'C' source line config statements // CONFIG1 #pragma config FEXTOSC = OFF // FEXTOSC External Oscillator mode Selection bits (Oscillator not enabled) #pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with 2x PLL (32MHz)) #pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2) #pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config MCLRE = ON // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config WDTE = OFF // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored) #pragma config LPBOREN = OFF // Low-power BOR enable bit (ULPBOR disabled) #pragma config BOREN = ON // Brown-out Reset Enable bits (Brown-out Reset enabled, SBOREN bit ignored) #pragma config BORV = LOW // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V) #pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a Reset) #pragma config DEBUG = OFF // Debugger enable bit (Background debugger disabled) // CONFIG3 #pragma config WRT = OFF // User NVM self-write protection bits (Write protection off) #pragma config LVP = ON // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored.) // CONFIG4 #pragma config CP = OFF // User NVM Program Memory Code Protection bit (User NVM code protection disabled) #pragma config CPD = OFF // Data NVM Memory Code Protection bit (Data NVM code protection disabled) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include <xc.h> #include <htc.h> #include <stdio.h> #include <stdint.h> #define _XTAL_FREQ 32000000 void i2c_is_idle(void){ //while(!PIR1bits.SSP1IF); //while(SSPCON2bits.SEN==1 || SSPCON2bits.RSEN==1 || SSPCON2bits.PEN==1 || SSPCON2bits.RCEN==1 || SSPCON2bits.ACKEN==1 || SSPSTATbits.R_nW==1){}; while(PIR1bits.SSP1IF == 0){ PORTCbits.RC2=1; }; // SSP1IF is set when operation complete PORTCbits.RC2=0; PIR1bits.SSP1IF = 0; // clear interrupt flag } void i2c_start(void){ i2c_is_idle(); SSPCON2bits.SEN = 1; } void i2c_rep_start(void){ i2c_is_idle(); SSPCON2bits.RSEN = 1; } void i2c_stop(void){ i2c_is_idle(); SSPCON2bits.PEN = 1; } void i2c_write(uint8_t i2c_data){ i2c_is_idle(); SSPBUF = i2c_data; while(SSPSTATbits.BF != 0); while(SSPCON2bits.ACKSTAT != 0); } uint8_t i2c_read(uint8_t ack){ uint8_t recieve =0; i2c_is_idle(); SSPCON2bits.RCEN = 1; while(SSPSTATbits.BF != 1); recieve = SSPBUF; SSPCON2bits.ACKEN = ack; return recieve; } void i2c_init(void){ TRISCbits.TRISC0 = 1; TRISCbits.TRISC1 = 1; SSPSTATbits.SMP = 1; SSPSTATbits.CKE = 0; SSPCONbits.SSPM = 0x08; SSPADD = 79; SSPCONbits.SSPEN = 1; } void main(void) { ANSELCbits.ANSC0 = 0; //ADC RC0 OFF ANSELCbits.ANSC1 = 0; //ADC RC1 OFF TRISCbits.TRISC2=0; //LED PIN TRISCbits.TRISC0=0; //MSSP bug counter TRISCbits.TRISC1=0; //MSSP bug counter //__delay_ms(5); LATCbits.LATC1=0; //MSSP bug counter LATCbits.LATC0=0; //MSSP bug counter //__delay_ms(5); INTCONbits.GIE=1; //global interrupt en INTCONbits.PEIE=1; //peripheral interrupt en ADCON0bits.ADON=0; //unpower adc just in case i2c_init(); //THIS SETS TRISC BITS FOR SCL SDA while(1){ i2c_start(); i2c_write(0x3C); i2c_stop(); } return; } Задача: просто увидеть коммуникацию на SCL SDA, я уже потом по даташитам таргет девайсов без проблем напишу дрова. Не получается именно осуществлять коммуникацию. Подскажите, пожалуйста, я не понимаю, где я дурак, а между тем волос на голове становится всё меньше, а те, что остались, стремительно приобретают серый окрас, ибо 2 недели я долбаюсь с одной проблемой. Благодарю за ваши советы. Спасибо.
-
Приветствую. Не получается запустить I2C на STM32F030F4P6 для общения с EEPROM. Использую StdPeriph. Сначала пробовал сам писать, потом взял код отсюда. Результат одинаков: На линиях активности нет, висит 3В. Через CubeMX все работает. Последний код, который я пробовал: void I2C_EEPROM_Init(void) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); GPIOA->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1; // Режим альтернативной функции GPIOA->OTYPER |= GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10; // Открытый коллектор GPIOA->OSPEEDR |= 0xFF<<18; // Максимальная скорость // Выбор альтернативной функции GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); // I2C1_SCL GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); // I2C1_SDA I2C_InitTypeDef I2C_InitStruct; I2C_InitStruct.I2C_Timing = 0x00402D42; I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Disable; I2C_InitStruct.I2C_DigitalFilter = 0x00; I2C_InitStruct.I2C_Mode = I2C_Mode_I2C ; I2C_InitStruct.I2C_OwnAddress1 = 0xDD; I2C_Init( I2C1, &I2C_InitStruct); I2C_Cmd(I2C1, ENABLE); } int main() { /* * ВКЛЮЧЕНИМЕ IWDG */ // включаем LSI RCC_LSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // разрешается доступ к регистрам IWDG IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // устанавливаем предделитель IWDG_SetPrescaler(IWDG_Prescaler_256); // значение для перезагрузки IWDG_SetReload(0xEA); // перезагрузим значение IWDG_ReloadCounter(); // LSI должен быть включен //IWDG_Enable(); /* * ВКЛЮЧЕНИМЕ IWDG ЗАВЕРШЕНО */ /* * Запуск ФАПЧ * Основная частота 48 МГц * UART от HSI */ RCC->CFGR |= 0xAA<<18; //pll mul = 12 RCC->CFGR |= 5<<8; //APB prescaller = 4 RCC->CFGR3 |= 3; //USART clock from HSI RCC->CR |= RCC_CR_PLLON; while ((RCC->CR | RCC_CR_PLLRDY) == 0); RCC->CFGR |= 2; //PLL as SYSCLK /* * Настройка ФАПЧ завершена */ //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // I2C_Initialization(); I2C_EEPROM_Init(); while (1) { I2C_TransferHandling(I2C1, 0xA0, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);//devAddr while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXE) == RESET);//TXDR empty I2C_SendData(I2C1, 0);//memAddr while(I2C_GetFlagStatus(I2C1, I2C_ISR_TCR) == RESET);//transmition complete I2C_TransferHandling(I2C1, 0xA0, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXE) == RESET); I2C_SendData(I2C1, 25); while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET); I2C_ClearFlag(I2C1, I2C_ICR_STOPCF); for (long int i = 0; i < 30000; i++) IWDG_ReloadCounter(); } } Прошу помощи с этой проблемой. Спасибо.
-
В общем понадобилось тут подвесить FRAM к STM32, а пины аппаратных I2C были уже заняты, ну решил не менять пины, а добавить себе на вооружение на всякий, программный I2C. То что удалось нагуглить либо работало криво, либо приходилось допиливать и допиливать. Ну и написал свой с блекджеком и ш.. Так как в сети примеров мало программного I2C на STM32 то решил поделиться. Вдруг кому пригодится. Работает с библиотекой HAL, поправить нужно только под свой камень и свои порты и все работает. I2C.h #ifndef __I2C_H_H__ #define __I2C_H_H__ // G1KuL1N // ПОДКЛЮЧИТЬ БИБЛИОТЕКУ СВОЕГО КОНТРОЛЛЕРА #include "stm32f4xx_hal.h" // В CUBE MX порты I2C настроить на выход (либо в main.c вручну подать тактирование на нужны GPIO) //---подключение шины к пинам----------------------------------------------------- #define SCL_I HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15); #define SDA_I HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_14); #define SCL_O HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET); #define SDA_O HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); //-------------------------------------------------------------------------------- void i2c_init (void); // Инициализация шины void i2c_start_cond (void); // Генерация условия старт void i2c_restart_cond (void); // Генерация условия рестарт void i2c_stop_cond (void) ; // Генерация условия стоп uint8_t i2c_send_byte (uint8_t data) ; //Передать байт (вх. аргумент передаваемый байт) (возвращает 0 - АСК, 1 - NACK) uint8_t i2c_get_byte (uint8_t last_byte) ; //Принять байт (если последний байт то входной аргумент = 1, если будем считывать еще то 0)(возвращает принятый байт) //-------------------------------------------------------------------------------- // ПРИМЕР ИСПОЛЬЗОВАНИЯ //========================================================================================= // Запись uint16_t во внешнюю еепром (FRAM FM24CL64) или любой другой 24LC памяти, // две ячейки, указывается адрес первой ячейки, следующая идет adr++ //========================================================================================= // //void FRAM_W_INT(uint16_t adr, uint16_t dat){ //i2c_start_cond (); //i2c_send_byte (0xA2); //адрес чипа + что будем делать (записывать) //i2c_send_byte ((adr & 0xFF00) >> 8); //i2c_send_byte (adr & 0x00FF); //i2c_send_byte ((dat & 0xFF00) >> 8); //i2c_send_byte (dat & 0x00FF); //i2c_stop_cond(); //} //========================================================================================= // Считывание uint16_t из внешней еепром (FRAM FM24CL64) или любой другой 24LC памяти, // две ячейки, указывается адрес первой ячейки, следующая идет adr++ //========================================================================================= //uint16_t FRAM_R_INT(uint16_t adr){ //uint16_t dat; //i2c_start_cond (); //i2c_send_byte (0xA2); //i2c_send_byte ((adr & 0xFF00) >> 8); //i2c_send_byte (adr & 0x00FF); //i2c_restart_cond (); //i2c_send_byte (0xA3); //dat = i2c_get_byte(0); //dat <<= 8; //dat |= i2c_get_byte(1); //i2c_stop_cond(); //return dat; //} // G1KuL1N #endif /* __I2C_H_H__ */ i2C.c #include "I2C.h" volatile uint8_t i2c_frame_error=0; //----------------------------------------------------------- __STATIC_INLINE void Delay_us (uint32_t __IO us) //Функция задержки в микросекундах us { us *=(SystemCoreClock/1000000)/5; while(us--); } //---------------------------------------------------- void SCL_in (void) //функция отпускания SCL в 1, порт на вход (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } //---------------------------------------------------- void SCL_out (void) //функция притягивания SCL в 0 (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); SCL_O; } //---------------------------------------------------- void SDA_in (void) //функция отпускания SDA в 1, порт на вход (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } //---------------------------------------------------- void SDA_out (void) //функция притягивания SDA в 0 (необходимо установить используемый порт) { GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); SDA_O } //---------------------------------------------------- void i2c_stop_cond (void) // функция генерации условия стоп { uint16_t SCL, SDA; SCL_out(); // притянуть SCL (лог.0) Delay_us(10); SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SDA_in(); // отпустить SDA (лог.1) Delay_us(10); // проверка фрейм-ошибки i2c_frame_error=0; // сброс счётчика фрейм-ошибок SCL=SCL_I; SDA=SDA_I; if (SCL == 0) i2c_frame_error++; // проберяем, чтобы на ноге SDA была лог.1, иначе выдаём ошибку фрейма if (SDA == 0) i2c_frame_error++; // проберяем, чтобы на ноге SCL была лог.1, иначе выдаём ошибку фрейма Delay_us(40); } void i2c_init (void) // функция инициализации шины { i2c_stop_cond(); // стоп шины i2c_stop_cond(); // стоп шины } //---------------------------------------------------- void i2c_start_cond (void) // функция генерации условия старт { SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } //---------------------------------------------------- void i2c_restart_cond (void) // функция генерации условия рестарт { SDA_in(); // отпустить SDA (лог.1) Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SDA_out(); // притянуть SDA (лог.0) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } //---------------------------------------------------- uint8_t i2c_send_byte (uint8_t data) // функция отправки байта { uint8_t i; uint8_t ack=1; //АСК, если АСК=1 – произошла ошибка uint16_t SDA; for (i=0;i<8;i++) { if (data & 0x80) { SDA_in(); // лог.1 } else { SDA_out(); // Выставить бит на SDA (лог.0 } Delay_us(10); SCL_in(); // Записать его импульсом на SCL // отпустить SCL (лог.1) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) data<<=1; // сдвигаем на 1 бит влево } SDA_in(); // отпустить SDA (лог.1), чтобы ведомое устройство смогло сгенерировать ACK Delay_us(10); SCL_in(); // отпустить SCL (лог.1), чтобы ведомое устройство передало ACK Delay_us(10); SDA=SDA_I; if (SDA==0x00) ack=1; else ack=0; // Считать ACK SCL_out(); // притянуть SCL (лог.0) // приём ACK завершён return ack; // вернуть ACK (0) или NACK (1) } //---------------------------------------------------- uint8_t i2c_get_byte (uint8_t last_byte) // функция принятия байта { uint8_t i, res=0; uint16_t SDA; SDA_in(); // отпустить SDA (лог.1) for (i=0;i<8;i++) { res<<=1; SCL_in(); // отпустить SCL (лог.1) //Импульс на SCL Delay_us(10); SDA_in(); SDA=SDA_I; if (SDA==1) res=res|0x01; // Чтение SDA в переменную Если SDA=1 то записываем 1 SCL_out(); // притянуть SCL (лог.0) Delay_us(10); } if (last_byte==0){ SDA_out();} // притянуть SDA (лог.0) // Подтверждение, ACK, будем считывать ещё один байт else {SDA_in();} // отпустить SDA (лог.1) // Без подтверждения, NACK, это последний считанный байт Delay_us(10); SCL_in(); // отпустить SCL (лог.1) Delay_us(10); SCL_out(); // притянуть SCL (лог.0) Delay_us(10); SDA_in(); // отпустить SDA (лог.1) return res; // вернуть считанное значение }
- 16 replies
-
- 3
-
-
Добрый день! Прошу помощи в реализации интерфейса TWI на XMEGA. Набросал код для двух микроконтроллеров. Но на выходе SDA и SCL вообще ничего не происходит. Привожу пример для мастера. #define F_CPU 2000000UL #define CPU_SPEED 2000000 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> uint8_t slave_address=6, write=0; uint8_t data=0x01; void TWI_init(void) { TWIC.CTRL=0; TWIC.MASTER.BAUD=0x05; TWIC.MASTER.CTRLA=TWI_MASTER_INTLVL_HI_gc|TWI_MASTER_ENABLE_bm|TWI_MASTER_WIEN_bm; TWIC.MASTER.CTRLB=0; TWIC.MASTER.CTRLC=0; TWIC.MASTER.STATUS=TWI_MASTER_BUSSTATE_IDLE_gc; } void TWI_write_date(uint8_t data) { //TWIC.MASTER.CTRLC=TWI_MASTER_CMD_REPSTART_gc; TWIC.MASTER.ADDR=slave_address|write; while(!(TWIC.MASTER.STATUS&TWI_MASTER_WIF_bm)); TWIC.MASTER.DATA=data; while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm)); TWIC.MASTER.DATA=data; while(!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm)); TWIC.MASTER.CTRLC=TWI_MASTER_ACKACT_bm|TWI_MASTER_CMD_STOP_gc; TWIC.MASTER.CTRLC=0; } int main(void) { CPU_SREG|=(1<<CPU_I_bp); TWI_init(); while(1) { TWI_write_date(data); } }
-
Не могу опросить магнитометр по I2C. На линиях какие-то сигналы проскакивают, но никакого результата не могу достичь. Кто-то что-то знает по этому поводу? Как заставить работать его. #include "stm32f30x.h" int a1=0, j=0; int main(void) { RCC->AHBENR|=RCC_AHBENR_GPIOBEN;// тактирование портa B включено RCC->AHBENR|=RCC_AHBENR_GPIOEEN;//21 тактирование портa Е включено RCC->APB1ENR|=RCC_APB1ENR_I2C1EN;// тактирование I2C1 включено GPIOB->MODER|=0x0000A000; // альтернативная функция линий PB7,PB6 GPIOB->OTYPER|=(1<<6); //настройка линии PB7 на выход открытый сток GPIOB->OTYPER|=(1<<7); //настройка линии PB6 на выход открытый сток GPIOB->OSPEEDR=0xFFFFFFFF; GPIOB->AFR[0] |= 0x44000000; //настройка линий PB7,PB6 на функцию AF4 GPIOE->MODER=0x55555555; //настройка порта Е на выход EXTI->EMR=1<<23; EXTI->IMR=1<<23; NVIC_EnableIRQ(I2C1_EV_IRQn); //инициализация I2C мастер I2C1->CR1=(0<<0); //PE=0 I2C1->TIMINGR=(0x4<<28);//PRESC[3:0]: Timing prescaler I2C1->TIMINGR=(0x8<<20);//SCLDEL[3:0]: Data setup time I2C1->TIMINGR=(0x8<<16);//SDADEL[3:0]: Data hold time I2C1->TIMINGR=(0xC3<<8);//SCLH[7:0]: SCL high period (master mode) I2C1->TIMINGR=(0xC7<<0);//SCLL[7:0]: SCL low period (master mode) I2C1->CR1=(0<<17);//для мастера = 0 NOSTRETCH: Clock stretching disable I2C1->CR1=(1<<6);//TCIE: Transfer Complete interrupt enable I2C1->CR1=(1<<2);//RXIE: RX Interrupt enable(RXNE) I2C1->CR1=(1<<1);//TXIE: TX Interrupt enable(TXIS) I2C1->CR2=(0<<11);//ADD10=0 -7 bits I2C1->CR2=(0<<10);//RD_WRN=0 передача I2C1->CR2=(1<<25);//AUTOEND I2C1->CR1|=(1<<0); //PE=1 I2C1->CR2 = 0x03<<1;//adress I2C1->CR2|=1<<13;//start ?????? a1=I2C1->RXDR; while (1){ // I2C1->CR2|=1<<13;//start if((a1&0x1)>0) GPIOE->ODR =1<<9; else GPIOE->ODR =(0<<9); if((a1 & 0x2)>0) GPIOE->ODR |=1<<10; else GPIOE->ODR &= ~(1<<10); if((a1 & 0x4)>0) GPIOE->ODR |=1<<11; else GPIOE->ODR &= ~(1<<11); if((a1 & 0x8)>0) GPIOE->ODR |=1<<12; else GPIOE->ODR &= ~(1<<12); if((a1 & 0x10)>0) GPIOE->ODR |=1<<13; else GPIOE->ODR &= ~(1<<13); if((a1 & 0x20)>0) GPIOE->ODR |=1<<14; else GPIOE->ODR &= ~(1<<14); if((a1 & 0x40)>0) GPIOE->ODR |=1<<15; else GPIOE->ODR &= ~(1<<15); if((a1 & 0x80)>0) GPIOE->ODR |=1<<8; else GPIOE->ODR &= ~(1<<8); }} void I2C1_EV_EXTI23_IRQHandler () {a1=2;}
-
Здравствуйте. Есть камера с шиной I2C и интерфейсом "Camera Port on 21 pin ZIF connector". Информация по сигналам в наличии. Есть ли возможность подключить её к ПК под управлением Linux/Window (не считая физического переходника 21 пин ZIF - ножки микросхемы)? Поиск по сети выдал следующий способ. В нём используется I2C-USB переходник из USBasp программатора и микросхема MCP23017 (I2C расширитель портов). Написано что микросхема MCP23017 имеет 16 I/O портов (из 28). Далее напрашивается вопрос, хватит ли выводов микросхемы что бы подключить камеру? Читаю спецификацию на микросхему и не донца понимаю, кажется хватает. Опционально, можно ли избавиться от самостоятельного изготовления связки I2C-USB переходник + MCP23017 а воспользоваться готовым? Есть ли в продаже адаптер I2C-USB с достаточным количеством портов? На AliExpress'е что-то не нашлось подходящего. MCP23017.pdf
-
Добрый день Возникла ситуация: имеется ноутбук IBM ThinkPad t20 с запароленым Bios. Пароль никто не помнит, но он зашит в 24rf08. Его можно прочитать програмкой для считывания данной микросхемы, но для этого нужен программатор. Можно ли использовать в качестве такого программатора Ардуино, чтобы он вопринимался этой программой как надо, и если можно, то как нужно подключить их и какой скетч залить в ардуинку? Саму программу выложу чуть позже, если необходимо - с мобильника сижу. Спасибо
-
Всем доброго времени суток! Кто-нибудь может поделиться рабочим примером инициализации I2C в STM32F030? Ну или может увидите в моём коде ошибку RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // Включаем тактирование RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; // Speed 50 MHz GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // Альтернативная функция GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // Без подтяжки GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // Открытый сток GPIO_Init(GPIOA, &GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // Режим работы (I2C) I2C_InitStructure.I2C_OwnAddress1 = 0x11; // Адрес (не важен, если устройство - мастер) I2C_InitStructure.I2C_Timing = 0x00300619; // Значение для записи в регистр I2C_TIMINGR I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Cmd(I2C1, ENABLE); I2C_Init(I2C1, &I2C_InitStructure); Полдня уже вожусь, никак не заводится. Компилится без ошибок, светодиод мигает (ну в основном цикле написана простая светодиодная мигалка и раз в секунду - отправка сообщения в I2C), но смотрю логическим анализатором - на ножках тишина (ну в смысле единичка всегда, они же подтянуты резисторами к плюсу) I2C_Timing рассчитывается калькулятором от ST (I2C Timing Configuration) на основе частоты тактирования модуля I2C, желаемой скорости шины и ещё пары параметров, калькулятор прикрепил к сообщению I2C_Timing_Configuration_V1.0.1.xls
-
Тема: Реверс-инжиниринг: необходимо декодировать протокол связи контроллера пром. насоса и дисплея Общая цель: сделать управление кондиционером, вести мониторинг его работы. Время на работу: около 12 часов (2 дня). Задание для исполнителя: 1. Выполнить обратное декодирование протокола связи контроллера промышленного кондиционера и его дисплея с сенсорными кнопками. 2. Запаять ATMega 328P или ATMega 2560. Вероятно, придется резать дорожки, допаять резисторы в разрыв. 3. Совместно с заказчиком написать короткий код ввода/вывода данных для Arduino (C++). Могут понадобиться функции передачи данных на второй контроллер ATMega 2560 по UART. 4. Совместно с заказчиком составить простое описание. 5. Работа дисплея, состояние контроллера кондиционера и мониторинг на Arduino должны быть синхронны. Программировать микроконтроллер и отправлять данные на вебсервер по Ethernet (W5500) умею. Паять умею. Работать с микроконтроллером на уровне регистров процессора не умею, потому и ставлю задание. Протокол: неизвестен Шина: неизвестна Чип дисплея: Holtek HT1621B Контроллер "пульта управления": Holtek BS84B08A-3 Фото прилагается. Вероятно, применяется шина SPI или I2C, что должно облегчить задачу. Имеется пример подобного дисплея 2009 года с выполненной работой. У предыдущего исполнителя ушло около 2 часов на разбор команд и еще столько же на написание кода, *когда поняли, как разбирать команды*. Фото с реализацией задания прилагается, но на дисплее другого типа. Метод выполненной работы в прошлый раз: 1. Для получения данных с Holtek-HT46F49E по 8-ми битной шине данных использован Arduino Pro Mini 328P. 2. Подключение: 5 дорожек перерезано и допаяно 5 резисторов по 1 кОм. Так же использовано еще 3 линии (reset и данные). 3. Для удаленного управления использована Arduino Mega 2560 + Ethernet Shield W5100. 4. Общение между 328P и 2560 идет по UART. Наилучший вариант, если кто-то откликнется из Киева, чтобы можно было вместе встретиться и поработать. Но если в Киеве никого нет, то куплю недорогой логический анализатор уровней и будем общаться удаленно. Готов к любому варианту.
-
Здравствуйте! Дано: BLE модуль JDY-10 Гироскоп + Акселерометр модуль GY-521 USB UART CH340G USB bluetooth адаптер Цель: передавать сигналы датчика гироскопа и акселерометра через bluetooth модуль на ПК. Мои рассуждения: Модуль GY-521 имеет I2C интерфейс, на JDY-10 стоит МК CC2541 который тоже имеет I2C интерфейс. Надо как-то их соединить и заставить отправлять показания на ПК. Как это сделать пока мне не понятно. Иногда приходят мысли что без перепрошивки контроллера не обойтись. Подскажите пожалуйста как это реализовать? П.С. В идеале вообще конечно использовать один контроллер для снятия значений и отправки на ПК, но пока так.
-
Всем привет. Решил сделать небольшую домашнюю метеостанцию. Есть приемник с экраном, куда выводится инфа (построено на ATMEGA 328P) и есть передатчик, который посылает инфу по возудху (построено на ATtiny85). В передатчике использую обычные DHT22. В принципе качество чуть ниже среднего. Но главный недостаток - порой сбоит, присылая данные в 2 раза больше предидущих, потом опять приходит в себя. и так повторяется постоянно. При этом время между измерениями не меньше 20 сек. В общем заказал я себе с Китаюшки более точные датчики - CJMCU-1080 HDC1080 Вещица прекрасная, но общается по I2C. А библиотеку рабочую под нее я смог найти только одну "ClosedCube_HDC1080.h" и никаких модификаций под ATtiny я найти не смог. Для ее работы соответственно нужен Wire.h В общем решил я его поковырять самостоятельно, хоть и не прогер. Забрался во внутренности ClosedCube_HDC1080.cpp и везде заменил Wire на TinyWireM (некий аналог Wire для ATtiny). И у меня даже получилось считывать валжность, но вот вместо температуры приходит гадость. Ибо при компиляции Arduino IDE ругалась на строку (я ее ниже в коде закомментировал) uint8_t buf[4]; for (int i = 1; i < (seconds*66); i++) { TinyWireM.beginTransmission(_address); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(20); TinyWireM.requestFrom(_address, (uint8_t)4); // TinyWireM.readBytes(buf, (size_t)4); } Ошибку пишет следующую: \ClosedCube_HDC1080.cpp: In member function 'void ClosedCube_HDC1080::heatUp(uint8_t)': \ClosedCube_HDC1080.cpp:81:13: error: 'class USI_TWI' has no member named 'readBytes' TinyWireM.readBytes(buf, (size_t)4); Может есть ребята более понимающие в коде и сумеющие победить эту проблему, чтобы и температуру этот датчик смог передавать через ATtiny85. Вот полный текст файла ClosedCube_HDC1080.cpp (уже замененный ну и строчка закоментирована): #include <TinyWireM.h> #include "ClosedCube_HDC1080.h" ClosedCube_HDC1080::ClosedCube_HDC1080() { } void ClosedCube_HDC1080::begin(uint8_t address) { _address = address; TinyWireM.begin(); // Heater off, 14 bit Temperature and Humidity Measurement Resolution TinyWireM.beginTransmission(_address); TinyWireM.write(CONFIGURATION); TinyWireM.write(0x0); TinyWireM.write(0x0); TinyWireM.endTransmission(); } HDC1080_Registers ClosedCube_HDC1080::readRegister() { HDC1080_Registers reg; reg.rawData = (readData(CONFIGURATION) >> 8); return reg; } void ClosedCube_HDC1080::writeRegister(HDC1080_Registers reg) { TinyWireM.beginTransmission(_address); TinyWireM.write(CONFIGURATION); TinyWireM.write(reg.rawData); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(10); } void ClosedCube_HDC1080::heatUp(uint8_t seconds) { HDC1080_Registers reg = readRegister(); reg.Heater = 1; reg.ModeOfAcquisition = 1; writeRegister(reg); uint8_t buf[4]; for (int i = 1; i < (seconds*66); i++) { TinyWireM.beginTransmission(_address); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(20); TinyWireM.requestFrom(_address, (uint8_t)4); // TinyWireM.readBytes(buf, (size_t)4); } reg.Heater = 0; reg.ModeOfAcquisition = 0; writeRegister(reg); } float ClosedCube_HDC1080::readT() { return readTemperature(); } float ClosedCube_HDC1080::readTemperature() { uint16_t rawT = readData(TEMPERATURE); return (rawT / pow(2, 16)) * 165 - 40; } float ClosedCube_HDC1080::readH() { return readHumidity(); } float ClosedCube_HDC1080::readHumidity() { uint16_t rawH = readData(HUMIDITY); return (rawH / pow(2, 16)) * 100; } uint16_t ClosedCube_HDC1080::readManufacturerId() { return readData(MANUFACTURER_ID); } uint16_t ClosedCube_HDC1080::readDeviceId() { return readData(DEVICE_ID); } uint16_t ClosedCube_HDC1080::readData(uint8_t pointer) { TinyWireM.beginTransmission(_address); TinyWireM.write(pointer); TinyWireM.endTransmission(); delay(9); TinyWireM.requestFrom(_address, (uint8_t)2); byte msb = TinyWireM.read(); byte lsb = TinyWireM.read(); return msb << 8 | lsb; }
-
Есть задача, опрашивать несколько ардуино по I2C с целью вывести полученное на дисплей. Рабочий код прикладываю, подсоединял по мануалу пробовал подтягивать SCL и SDA резисторами на 1,5кОм. Вопрос в следующем. Почему то поле некоторого времени слейв перестает определятся. Скан видит любую перефирию I2C кроме ардуинки Код (C++): Код мастера #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x26,16,2); #include <Wire.h> char co = 0 ; void setup() { Wire.begin(); // join i2c bus (address optional for master) lcd.init(); lcd.backlight(); Serial.begin(9600); } void loop() { Wire.requestFrom(0x10, 4,true); lcd.setCursor(0,0); while (Wire.available()) { co = Wire.read(); Serial.print(co); lcd.print(co); } delay(200); Serial.print(" "); Wire.requestFrom(0x10, 7,true); // request 6 bytes from slave device #8 lcd.setCursor(4,0); while (Wire.available()) { co = Wire.read(); Serial.print(co); lcd.print(co); } Serial.print("\n"); delay(200); lcd.clear(); } Код (C++): Код слейва 01 #include <Wire.h> 02 03 byte stat = true; 04 05 char c[4] = {'N','O',' ',' '}; 06 float x = 322.345; 07 void setup() { 08 Wire.begin(0x10); 09 pinMode(13, OUTPUT); 10 Serial.begin(9600); 11 Wire.onRequest(requestEvent); 12 } 13 14 void loop() { 15 digitalWrite(13, LOW); 16 delay(100); 17 18 } 19 20 void requestEvent() { 21 if (stat == true) 22 { 23 24 Wire.write(c,sizeof c); 25 stat = false; 26 }else 27 { 28 char outstr[7]; 29 dtostrf(x,7, 3, outstr); 30 Wire.write(outstr,sizeof outstr); 31 stat = true; 32 } 33 digitalWrite(13, HIGH); 34 35 36 37 38 }
-
Всем привет. Существуют ли готовые модули для измерения мгновенных значений тока и напряжения (ток до 100 А, напряжение до 250 вольт)? Т.е. измерять нужно с частотой 1000-5000 герц, точность 14-16 бит, связь по SPI лучше всего. Вообще нужно хотя-бы 4 канала по току и 4 по напряжению. Но лучше, чтобы можно было на одну шину ставить несколько модулей, расширяя количество каналов. Обрабатывать данные собираюсь на STM32F104 (хотя с ним никогда не работал) или Arduino Due, но это не важно. Понятно что можно взять АЦП и шунт или делитель напряжения, но хотелось бы готовый модуль и уже с оптической развязкой. Подскажите если кто сталкивался.
-
Люди добрые, помогите кто может! потому что имею HD44780 + PCF8547, хотел сделать i2c library. скажите пожалуйста где делаю неправильно. прикрепляю PrintScreen от Proteus ISIS #include <htc.h> #define _XTAL_FREQ 4000000 //******************************************************** #pragma config FOSC = INTRC_CLKOUT// Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) #pragma config LVP = ON // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled) // CONFIG2 #pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) #pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off) //******************************************************** #define LCD_DISPLAYMODE 0x08 #define pic_frq 16000 // controller frequenc #define i2c_frq 400 // #define gen_frq (((pic_frq / i2c_frq) / 4) - 1) void i2cByteWrite(char, char, char); void i2cTxData(char); void LCD_dat(char); void LCD_cmd(char); void LCD_clr(void); void LCD_int(void); void LCD_str(char *); void LCD_ROMstr(const char *); void LCD_posyx(char,char); void LCD_hex(char); void i2c_init(); //////////// Main ////////////////////////////////// void main(void){ char msgStart[] ="LCD Work"; unsigned char num = 0; OSCCON = 0b00110000; //4Mhz TRISC = 0b11111111; PORTC = 0x00; i2c_init(); LCD_int(); // ------------------------------------------------------ LCD_str(msgStart); // LCD_dat(' '); LCD_dat('!'); // ------------------------------------------------------ LCD_posyx(1,0); // LCD_ROMstr("12345"); while(1){ LCD_posyx(0,14); // LCD_hex(num++); // __delay_ms(1000); // 1000msec } } void i2c_init() { TRISC3 = 1; TRISC4 = 1; SSPSTAT = 0b10000000; // Slew rate disabled SSPCON = 0b00101000; //(0x28) SSPEN = 1, I2C Master mode, clock = FOSC/(4*(SSPADD+1)) SSPCON2 = 0b00000000; // SSPADD = gen_frq; } // ----------------------------------------------------------- void i2cByteWrite(char addr, char cont, char data){ SEN = 1; // Start condition while(SEN); // if (Start condition) i2cTxData(addr); // i2cTxData(cont); // i2cTxData(data); // SSPIF = 0; // PEN = 1; // Stop condition while(PEN); // Stop condition } void i2cTxData(char data){ SSPIF = 0; // SSPBUF = data; // while(!SSPIF); // } // ----------------------------------------------------------- void LCD_dat(char chr){ i2cByteWrite(0xA0, 0x80, chr); __delay_us(60); // 60 usec } // ----------------------------------------------------------- void LCD_cmd(char cmd){ i2cByteWrite(0xA0, 0x00, cmd); if(cmd & 0xFC) // __delay_us(60); // 60usec else __delay_ms(3); // 3msec } // ----------------------------------------------------------- void LCD_clr(void){ LCD_cmd(0x01); //Clear Lcd } void LCD_posyx(char ypos, char xpos){ unsigned char pcode; switch(ypos & 0x03){ // case 0: pcode=0x80;break; // 1line case 1: pcode=0xC0;break; // 2line case 2: pcode=0x94;break; // 3line case 3: pcode=0xD4;break; // 4line } LCD_cmd(pcode += xpos); // } // ----------------------------------------------------------- void LCD_str(char *str){ while(*str) // LCD_dat(*str++); // } // ----------------------------------------------------------- void LCD_ROMstr(const char *str){ while(*str) // LCD_dat(*str++); // } // ----------------------------------------------------------- void LCD_hex(char c){ const char hexch[] ="aaaa"; LCD_dat(hexch[c >> 4]); // LCD_dat(hexch[c & 0xF]); // } // ----------------------------------------------------------- void LCD_int(void){ __delay_ms(100); // LCD_cmd(0x28); // 4 bit mode LCD_cmd(LCD_DISPLAYMODE | 0x00); // Display on Cursor=0 Blink=0 LCD_cmd(0x06); // Entry Inc/Dec=1 Shift=0 LCD_cmd(0x01); // Clear Display }
-
Хочу сделать, чтобы контроллер опознавал самостоятельно факт подключения к линии i2c внешних устройств. Предполагаю периодически рассылать запросы на запись по каждому адресу и записывать, пришло ли подтверждение или нет, после чего сразу прерывать работу стоп-битом. Возникает вопрос - как поведет себя другой контроллер, если он подтвердит готовность принять некие данные а в результате вместо тактов он получит стоп-бит? Может, в стандарте i2c есть общепринятый метод опроса адресов?
-
Добрый день. Пытаюсь сделать конвеер для аппаратного TWI модуля ATMega8. Контроллер в режиме мастера периодически работает с 4 разными устройствами на шине. LCD1602 висит также на шине I2C. Инициализация проходит информация на LCD выводится. Далее идёт процесс опроса времени с DS3231. Время передаётся но в конце при передаче СТОП на линию І2С. СТОП не проходит. Логический анализатор показывает на линии SCL - 1, SDA - 0. В регистре статуса F8. Ожидание ни к чему не приводит. Продолжение кода тоже. Как с этим бороться может кто сталкивался.
-
Здравствуйте! Имею в наличии 7-ми дюймовый экран от портативного DVD плеера. На фото ресивер на процессоре (чипе) mx88v462. В поисках в интернете для Arduino готовых библиотек не нашел. Но натолкнулся на странички на форуме, http://radiokot.ru/f...068630#p2068630 http://radiokot.ru/f...p?f=61&t=105858 Изначально не мог даже перенести библиотеки из Avr Studio в Arduino. На форуме, добрый человек помог, за что ему большое спасибо.. http://forum.amperka...иблиотеки.6538/ Код для Arduino: //не правильно работает mx88v462_2.zip Код для Avr Studio: //работает на Atmega16 MX88V462.zip Разница между проектами в том что разделен файл на *.cpp и *.h Но на Arduino код не работает, а точнее не совсем правильно, дисплей не инициализируется... Код для Avr точно рабочий, так как создал проект в Avr Studio для Atmega16, скомпилировал, получил hex файл, залил той же ArduinoЙ. MX88V462.zip И результат: Но проблема, перенесенная библиотека для Arduino не работает, дисплей не инициализируеться... Ресивер для дисплей работает по протоколу I2C. В проекте в Avr Studio реализован программный I2C, что и написано на форуме автора данной библиотеки. http://radiokot.ru/f...068630#p2068630 http://radiokot.ru/f...p?f=61&t=105858 В проекте для Arduino было опробовано и программный I2C и при помощи Wire. Но дисплей не инициализируется.. Потом в Proteus подключил Atmega328 и Atmega16. В Atmega328 залил hex файл скомпилированным в Aruino IDE // тот что не правильно работает В Atmega16 залил hex файл, тот с которым инициализировался дисплей и вывел текст. Подключил осциллограф к SDA SCL обеих микроконтроллеров. Chanel A - желтый -> SDA Atmega328 Chanel B - синий -> SCL Atmega328 Chanel C - красный -> SDA Atmega16 Chanel D - зеленый -> SCL Atmega16 И проблема в том, что сигналы не совпадают, скважность и сам сигнал. Частота кварцов выставлена одинаковая, 16M Видно что сам сигнал и скважность разная, думаю из за этого дисплей не инициализируется. При том что код почти одинаковый.. Пожалуйста, помогите решить данный вопрос, очень надо поднять данный дисплей... Буду очень благодарен.
-
- MX88V462
- Перенос библиотеки
-
(and 7 more)
Tagged with:
-
Нашел старый телевизор, и увидел в нем аудиопроцессор ta8776n скачал даташит, посмотрел что можно сделать LPF то есть фнч. Там есть выходы L+R,и L-R и просто L R. Вопрос вот в чем: Какие выходы фильтрованные, а какие нет. P s я знаю что микросхема контролируется через I2C. ta8776n.pdf
-
{BASCOM-AVR} Всем доброго времени суток! Я вот тут твёрдо решил собрать аудио-ресивер на основе atmega8 и собственно, TDA7439. С мегой понятно всё (ну почти ), а вот с TDA не очень... А если быть точнее, то с i2c управлением. В даташите есть принцип работы i2c на микрухе, но мне эти таблицы не очень понятны... Помогите разобратся. Мне понятен такой вариант, например, i2cstart i2cwbyte адрес i2cstart i2cwbyte код i2cstop DATASHEET: TDA7439.pdf
-
вопрос к разбирающимся. есть управляющее устройство (одноплатный комп типа raspberry pi или МК, значения не имеет). есть внешняя плата расширения портов. как правильно подключить ее к управляющему устройству по интерфейсу i2c? прикрепил картинку. вопросы поконкретнее: можно ли подключать так, как на картинке? резисторы подтяжки линии i2c нужны на каждой плате свои? или лучше поставить их только на управляющей плате, а остальные платы соединить напрямую? можно ли подтягивать линию i2c к 5 вольтам, полученным после стабилизатора 7805?
-
Всем привет. Столкнулся с проблемой, может кто уже сталкивался с подобным, или может хоть подскажите в какую сторону смотреть. Дело вот в чём: простая тестовая программа, передранная целиком и полностью из интернета(упростил в процессе поиска глюка, потом по функциям всё разложу) передаёт число 0х44 в устройство с адресом 0х12 по I2C. Настроил тактирование контроллера, порты и сам интерфейс. Бросаю стартовый бит, нормально. Бросаю адрес, отлично. Отсылаю байт данных, а на выходе идёт 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){ } }
-
Доброго времени суток. Стоит задача измерение температуры на улице и дома с выводом на LiquidCrystal_I2C дисплей, вообщем всё по стандарту только без ардуины а на чипе tiny2313, возможно ли это? Если да то как прописать пины на 2313 для LiquidCrystal_I2C. Шью 2313 с помощью arduino uno. Заранее спасибо.
- 9 replies
-
- ATTINY2313
- I2C
-
(and 1 more)
Tagged with:
-
Всем добрый день! Пишу в надежде, что кто-то-нибудь пытался связаться с этим датчиком аппаратным i2c. На деле он воспринимает только программный вариант. А так чтоб подключить модуль MSSP - это неет! Среда mplab 8.92, С18 compiler. Данный компилятор имеет хорошую библиотеку функций i2c. Задание мое такое - увидеть (хотя бы!) на осциллографе линию тактирования и прочитать два байта данных от датчика. Вот листинг: #pragma config OSC = INTOSC, FCMEN = OFF, IESO = OFF, MSSP7B_EN = MSK7 #pragma config DSBOREN = OFF #pragma config WDTEN = OFF, WDTPS = 32768, DSWDTEN = OFF #pragma config LPT1OSC = OFF #pragma config STVREN = ON, XINST = OFF, T1DIG = OFF #pragma config RTCOSC = INTOSCREF #pragma config DSWDTOSC = INTOSCREF, IOL1WAY = OFF #pragma config WPFP = PAGE_0, WPEND = PAGE_0, WPCFG = OFF, WPDIS = OFF /** I N C L U D E S **************************************************/ #include <p18f25j50.h> #include <i2c.h> // header file #include <delays.h> #include <math.h> #define measure_temp 0x03 #define measure_humidity 0x05 #define pic_frq 500 // кГц - частота контроллера #define i2c_frq 100 // кГц - частота обмена // расчет коэф генератора #define gen_frq (((pic_frq / i2c_frq) / 4) - 1) /** V A R I A B L E S *************************************************/ #pragma udata // declare statically allocated uinitialized variables unsigned char buff[2]={0,0}; // 8-bit variable int temp; /** D E C L A R A T I O N S *******************************************/ #pragma code // declare executable instructions void main (void) { TRISBbits.TRISB4 = 1; TRISBbits.TRISB5 = 1; PORTA = PORTB = PORTC = 0; OpenI2C1 (MASTER, SLEW_OFF); SSP1ADD = gen_frq; IdleI2C1(); StartI2C1(); IdleI2C1(); WriteI2C1( measure_temp ); IdleI2C1(); buff[0] = ReadI2C1(); AckI2C3(); buff[1] = ReadI2C1(); NotAckI2C1(); StopI2C1(); temp = buff[0] << 8; temp = temp + buff[1]; } Линия данных стоит в положении ВЫСОКОЕ, линия тактирования молчит. Отладчик тем не менее доходит до функции ReadI2C1(), типа он там ждет что появится флаг заполнения буфера. ...............про этот датчик я где-то на западном форуме увидел отзыв "It's notI2c sensor". В ДШ условие старта отличается от общепринятого для i2c. Сломал себе мозги. Думаю завести фляжечку с беленькой...