/**************************************************************************************************** * @fn I2C_HardwareSetup * Configures the GPIOs and h/w interface for the I2C bus * * @param busId - I2C bus identifier in case multiple buses are supported * * @return true if successful, false otherwise. * ***************************************************************************************************/ osp_bool_t I2C_HardwareSetup( I2C_TypeDef *busId ) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; if (busId == I2C_SENSOR_BUS) { if (sI2C_Bus1Initialized) { return true; } /* Reset the peripheral (this allows soft restarts to recover the bus in case of hangups) */ I2C_DeInit(busId); /* Enable Clocks to the peripheral and GPIOs used */ RCC_APB1PeriphClockCmd(RCC_Periph_I2C_SENSOR_BUS, ENABLE); RCC_APB2PeriphClockCmd(RCC_Periph_I2C_SENSOR_BUS_GPIO, ENABLE ); //for I2C port GPIO /* NVIC/Interrupt config */ /* Configure and enable I2C event interrupt -------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C_SENSOR_BUS_EVENT_IRQ_CH; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = I2C_SENSOR_BUS_INT_PREEMPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C_SENSOR_BUS_EVENT_INT_SUB_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C error interrupt -------------------------------*/ NVIC_InitStructure.NVIC_IRQChannel = I2C_SENSOR_BUS_ERROR_IRQ_CH; NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C_SENSOR_BUS_ERROR_INT_SUB_PRIORITY; NVIC_Init(&NVIC_InitStructure); /* GPIO Configuration for CLK and SDA signals */ GPIO_InitStructure.GPIO_Pin = I2C_SENSOR_BUS_CLK_PIN | I2C_SENSOR_BUS_SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( I2C_SENSOR_BUS_GPIO_GRP, &GPIO_InitStructure ); //Init the I2C driver interface I2C_Master_Initialise(); /* Do a software reset after enabling master I2C clock - this takes care of BUSY condition */ I2C_SoftwareResetCmd( I2C_SENSOR_BUS, ENABLE ); I2C_SoftwareResetCmd( I2C_SENSOR_BUS, DISABLE ); /* Now we need to do Master init again */ I2C_Master_Initialise(); sI2C_Bus1Initialized = true; return true; } return false; }
/** * Function used to read the temperature using Chico's Heat Sensor. There are 9 * sensors total: 1 for ambient temperature and the others form the 8-bit temperature * gauge sensor. * * @params temp: Pointer to an array to contain temperature values * @returns temp: ambient and all 8-bit temperature values */ int * ReadTemperature(int* temp) { for (int i = 0; i < 9; i++) { /// Start the sequence by initializing the master I2C_Master_Initialise(writeAddress); I2C_Master_Start_Transceiver_With_Data((writeData + (i * 2)), 2); I2C_Master_Start_Transceiver_With_Data(readData, sizeof(readData)); I2C_Master_Get_Data_From_Transceiver(result + (i * 2), 2); } int counter = 1; ///Finding the average ambient temp for (int i = 0; i < 10; i++) { if (i == 9) { temp[i] = (temp[1] + temp[2] + temp[3] + temp[4] + temp[5] + temp[6] + temp[7] + temp[8]) / 8; } else { temp[i] = *(result + counter); counter = counter + 2; } } return temp; }
int main(void) { // turn on the serial port for setting or querying the time . xSerialPort = xSerialPortInitMinimal( USART0, 115200, portSERIAL_BUFFER_TX, portSERIAL_BUFFER_RX); // serial port: WantedBaud, TxQueueLength, RxQueueLength (8n1) // Memory shortages mean that we have to minimise the number of // threads, hence there are no longer multiple threads using a resource. // Still, semaphores are useful to stop a thread proceeding, where it should be stopped because it is using a resource. if( xADCSemaphore == NULL ) // Check to see if the ADC semaphore has not been created. { xADCSemaphore = xSemaphoreCreateBinary(); // binary semaphore for ADC - Don't sample temperature when hands are moving (voltage droop). if( ( xADCSemaphore ) != NULL ) xSemaphoreGive( ( xADCSemaphore ) ); // make the ADC available } // initialise I2C master interface, need to do this once only. // If there are two I2C processes, then do it during the system initiation. I2C_Master_Initialise((ARDUINO<<I2C_ADR_BITS) | (pdTRUE<<I2C_GEN_BIT)); avrSerialxPrint_P(&xSerialPort, PSTR("\r\nHello World!\r\n")); // Ok, so we're alive... xTaskCreate( TaskWriteLCD , (const portCHAR *)"WriteLCD" , 192 , NULL , 2 , NULL ); // */ xTaskCreate( TaskWriteRTCRetrograde , (const portCHAR *)"WriteRTCRetrograde" , 120 , NULL , 1 , &xTaskWriteRTCRetrograde ); // */ xTaskCreate( TaskMonitor , (const portCHAR *)"SerialMonitor" , 256 , NULL , 3 , NULL ); // */ avrSerialPrintf_P(PSTR("\r\nFree Heap Size: %u\r\n"), xPortGetFreeHeapSize() ); // needs heap_1, heap_2 or heap_4 for this function to succeed. vTaskStartScheduler(); avrSerialPrint_P(PSTR("\r\n\nGoodbye... no space for idle task!\r\n")); // Doh, so we're dead... #if defined (portHD44780_LCD) lcd_Locate (0, 1); lcd_Print_P(PSTR("DEAD BEEF!")); #endif }
/**************************************************************************************************** * @fn I2C_HardwareSetup * Configures the GPIOs and h/w interface for the I2C bus * * @param busId - I2C bus identifier in case multiple buses are supported * * @return true if successful, false otherwise. * ***************************************************************************************************/ osp_bool_t I2C_HardwareSetup( I2C_TypeDef *busId ) { if (busId == LPC_I2C0) { if (sI2C_Bus1Initialized) { return true; } /* Configure the I2C interface in Master mode with the given speed */ Chip_IOCON_PinMuxSet(LPC_IOCON, I2C_SENSOR_BUS_SCL_PIN); Chip_IOCON_PinMuxSet(LPC_IOCON, I2C_SENSOR_BUS_SDA_PIN); Chip_I2C_Init(busId); /* Enables clock and resets the peripheral */ /* setup speed and config. as Master */ Chip_I2C_SetClockDiv( busId, I2C_MASTER_CLOCK_DIV ); Chip_I2CM_SetBusSpeed( busId, I2C_MCLOCK_SPEED ); /* Reset master state machine */ Chip_I2CM_Disable( busId ); Chip_I2CM_Enable( busId ); /* Enable interrupt for pending status */ Chip_I2C_EnableInt( busId, I2C_INTENSET_MSTPENDING ); I2C_Master_Initialise(); /* Configure TWI interrupts */ NVIC_SetPriority( I2C_SENSOR_BUS_IRQn, I2C_SENSOR_BUS_INT_PRIORITY ); NVIC_EnableIRQ( I2C_SENSOR_BUS_IRQn ); //enable I2C isr sI2C_Bus1Initialized = true; return true; } return false; }
int main() { //! Инициализация портов для светодиодов. DDRF |= (1 << DDF0 | 1 << DDF1 | 1 << DDF2 | 1 << DDF3); //! Инициализация порта для пьезоизлучателя. DDRB |= (1 << DDB0); //! Инициализация портов для строк клавиатуры. Строки на ввод. DDRD &= ~(1 << DDD4 | 1 << DDD5 | 1 << DDD6 | 1 << DDD7); //! Инициализация портов для строк клавиатуры. Поддяжка к питанию. PORTD |= (1 << PD4 | 1 << PD5 | 1 << PD6 | 1 << PD7); //! Инициализация портов для столбцоы клавиатуры. столбцы на вывод. DDRG |= (1 << DDG0 | 1 << DDG1 | 1 << DDG2); //! Инициализация таймера для излучателя звука. TCCR3A = 0; TCCR3A = 0; TCCR3B = 0; TCCR3B_struct.cs3 = 0x01; // Предделитель: F_CPU/1 TIMSK3_struct.toie3 = 1; // Разрешаем прерывание по переполнению TCNT3 = -8000; // 8000 тактов центрального проессора ~ 500 мкс. //! Инициализация таймера для смены режимов. TCCR4A = 0; TCCR4A = 0; TCCR4B = 0; uint8_t key1, key2 = 0; //!< Переменные для хранения кода нажатых клавишь. uint8_t i; char tx_buff_str[16]; //! Структура для чтения времени. //! Перед первым использованием должна быть инициализирована. ds18b20_memory_t ds18b20_memory = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int16_t temper = 0; //! Структура для чтения времени. //! Перед первым использованием должна быть инициализирована. rtc_data_r_t time = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //rtc_data_w_t time_w = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //!< Структура для установки времени. uint8_t sec; I2C_Master_Initialise(); //!< Инициализация I2C интерфейса. ds18b20_convert(); //!< Запуск преобразование температуры. uart_init(); //!< Инициализируем UART. uart_set_input_cb(uart_rx_cb);// Устанавливаем функцию обратного вызова на прием байта по UART. printf("\n\rLESO laboratory (c) 2014\r\nDemo test program\r\n"); printf("LESO6 ATMEGA128RFA1\r\n"); fprintf(stderr, "stderr: NO ERRORS\r\n"); //! Массив с описанием символа градуса. uint8_t ch[8] = { 0x06, /*x x x 0 0 1 1 0*/ 0x09, /*x x x 0 1 0 0 1*/ 0x09, /*x x x 0 1 0 0 1*/ 0x06, /*x x x 0 0 1 1 0*/ 0x00, /*x x x 0 0 0 0 0*/ 0x00, /*x x x 0 0 0 0 0*/ 0x00, /*x x x 0 0 0 0 0*/ 0x00 /*x x x 0 0 0 0 0*/ }; //! Управлящая структура для ЖКИ. lcd_t lcd = { 0, 0, 0, 0, 0 }; lcdInit(&lcd); //!< Инициализируем ЖКИ; lcdCursor(&lcd, 0); //!< Выключаем курсор. lcdCursorBlink(&lcd, 0); //!< Выключаем мерцание курсора. sprintf(tx_buff_str, " LESO6 \n 2014%c ", 0xb4); lcdPuts(&lcd, tx_buff_str); lcdCharDef(&lcd, 1, ch); //!< Определяем новый символ. for (i = 0; i < 75; i++) _delay_ms(10); getTimeDS1338(&time); //!< Читаем время. ds18b20_read(&ds18b20_memory); //!< Читаем температуру. sec = time.Second; TIMSK3_struct.toie3 = 0;// Запрещаем прерывание при переполнении таймера 3. off(BIP); // Выключаем звук. lcdClear(&lcd); lcdCursor(&lcd, 1); lcdPuts(&lcd, "Text:\n"); while (1) { while (key_mode) // В режиме набора текст: { key1 = getKeyChar(); for(i=0; i<5; i++) _delay_ms(10); key2 = getKeyChar(); if (key1 == '\n') continue; else if (key1 != key2) continue; TCNT4 = 0; // Дополнительное время работы в этом режиме if((lcd.cx) == lcd.cols)// закончились символы в строке { lcdPuts(&lcd,"\r \r");// стираем строку, возвращаем курсор в начало printf("\r\033[0K");// стираем строку в терминале } lcdPutchar(&lcd, key1); LEDS &= ~0x0F; LEDS |= 0x0F&key1; putchar(key1); TIMSK3_struct.toie3 = 1; // пик for(i=0; i<20; i++) _delay_ms(10); TIMSK3_struct.toie3 = 0; } printf("\r\033[0K%02u:%02u:%02u",time.Hour, time.Minute ,time.Second); sprintf(tx_buff_str, "%02u:%02u:%02u\n",time.Hour, time.Minute ,time.Second); lcdHome(&lcd); lcdPuts(&lcd, tx_buff_str); if(ds18b20_crc8((uint8_t *)&ds18b20_memory, sizeof(ds18b20_memory))) fprintf(stderr,"ERROR read DS18B20\r\n"); else { temper = (ds18b20_memory.temper_MSB << 8) | ds18b20_memory.temper_LSB; printf(" T= %d.%u",temper>>4, ((temper&0xf)*1000)/(16)); sprintf(tx_buff_str,"%02d.%u%cC ",temper>>4, ((temper&0xf)*1000)/(16), 0x01); lcdPuts(&lcd, tx_buff_str); } ds18b20_convert(); // Запуск преобразование температуры. while(sec == time.Second) { if (getTimeDS1338(&time)) { fprintf(stderr,"ERROR: read date fail..!\n\r"); continue; } key1 = getKeyChar(); if (key1 != '\n') { key_mode = 1; lcdClear(&lcd); lcdCursor(&lcd, 1); lcdPuts(&lcd,"Text:\n"); TCCR4B_struct.cs4 = 0x04; // Предделитель: F_CPU/256 TIMSK4_struct.toie4 = 1;// Разрешаем прерывание по переполнению TCNT4 = 0; printf("\r\033[0K");// стираем строку в терминале break; } for(i=0; i<20; i++) _delay_ms(10); } sec = time.Second; ds18b20_read(&ds18b20_memory); if(ds18b20_crc8((uint8_t *)&ds18b20_memory, sizeof(ds18b20_memory))) fprintf(stderr,"ERROR read DS18B20\r\n"); } return 0; }