Доброго времени суток. Прошерстил темки, но решения своей проблемы не нашел. А суть вот в чем: пытаюсь разобраться с аппаратным twi, использую atmega32a, wh1601a и ds1338, как видно из темы. С дисплеем разобрался, а вот с часами не смог. Пытаюсь вытащить секунды из rtc и вывести их на дисплей. Скурил море даташитов и прочитал кучу статей, но данных из rtc добиться не смог. Привожу код ниже, помогите найти ошибку пожалуйста. В МК совсем плох, но активно осваиваю.
| Код | /* * display.c * * Created: 09.07.2013 11:28:44 * Author: George Yarmak */
#define F_CPU 1600000 #define F_SCL 10000
#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h>
// ds1338 defines #define ds_address 11010000 #define TWI_START 0 #define TWI_RESTART 1 #define TWI_STOP 2 #define TWI_TRANSMIT 3 #define TWI_RECEIVE_ACK 4 #define TWI_RECEIVE_NACK 5
//LCD Port defines #define LCD_DDR DDRA #define LCD_OUT PORTA #define LCD_IN PINA #define E 2 #define RW 1 #define RS 0 #define D7 7 #define D6 6 #define D5 5 #define D4 4
#define SetBit(reg, bit) reg |= (1<<bit) #define ClearBit(reg, bit) reg &= (~(1<<bit)) #define InvBit(reg, bit) reg ^= (1<<bit) #define BitIsSet(reg, bit) ((reg & (1<<bit)) != 0) #define BitIsClear(reg, bit) ((reg & (1<<bit)) == 0)
void LCD4Char(uint8_t ch) { LCD_OUT=(ch&0b11110000); LCD_OUT|=1<<RS; LCD_OUT|=1<<E; _delay_ms(2); LCD_OUT&=~(1<<E); LCD_OUT&=~(1<<RS); _delay_ms(2); LCD_OUT=((ch&0b00001111)<<4); LCD_OUT|=1<<RS; LCD_OUT|=1<<E; _delay_ms(2); LCD_OUT&=~(1<<E); LCD_OUT&=~(1<<RS); _delay_ms(2); }
void LCD4_cmd(uint8_t cmd) { LCD_OUT=(cmd&0b11110000); LCD_OUT|=1<<E; _delay_ms(2); LCD_OUT&=~(1<<E); _delay_ms(2); LCD_OUT=((cmd&0b00001111)<<4); LCD_OUT|=1<<E; _delay_ms(2); LCD_OUT&=~(1<<E); _delay_ms(2); }
void LCD_cmd(uint8_t cmd) { LCD_OUT=cmd; SetBit(LCD_OUT,E); _delay_ms(2); ClearBit(LCD_OUT,E); _delay_ms(2); }
void LCD4_init(void) { LCD_DDR=(1<<E)|(1<<RS)|(1<<RW)|(1<<D7)|(1<<D6)|(1<<D5)|(1<<D4); _delay_ms(40); //function set 0 //8-bit LCD_cmd(0b000110000); //function set 1 //8-bit LCD_cmd(0b000110000); //function set 2 //set 4-bit mode LCD4_cmd(0b00100000); //function set 3 //4-bit mode LCD4_cmd(0b00100000); //display on //set blink cursor LCD4_cmd(0b00001100); //display clear LCD4_cmd(0b00000001); //entry mode set LCD4_cmd(0b00000010); }
void twi_init(void) { TWBR=(F_CPU/F_SCL-16)/2; TWSR=0x00; TWDR = 0xFF; // Default content = SDA released. TWCR = 0; TWCR = (1<<TWEN)|(0<<TWIE)|(0<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC); }
uint8_t TWI(uint8_t action){ switch(action){ case TWI_START: case TWI_RESTART: TWCR = _BV(TWSTA) | _BV(TWEN) | _BV(TWINT);// | _BV(TWIE); break; case TWI_STOP: TWCR = _BV(TWSTO) | _BV(TWEN) | _BV(TWINT);// | _BV(TWIE); break; case TWI_TRANSMIT: TWCR = _BV(TWEN) | _BV(TWINT);// | _BV(TWIE); break; case TWI_RECEIVE_ACK: TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);//| _BV(TWIE); break; case TWI_RECEIVE_NACK: TWCR = _BV(TWEN) | _BV(TWINT);// | _BV(TWIE); break; } if(action != TWI_STOP)while (!(TWCR & _BV(TWINT))); return (TWSR & 0xF8); }
unsigned char TWI_Transceiver_Busy( void ) { while (!(TWCR & (1<<TWINT))); //Wait for TWINT Flag set. This indicates that the START condition has been transmitted }
int main(void) { twi_init(); LCD4_init(); uint8_t sec;
while(1) { //TWI_Transceiver_Busy(); // Wait until TWI is ready for next transmission. TWI(TWI_START); //start TWDR=ds_address; //target device address (ds1338) TWI(TWI_TRANSMIT); //transmit TWI(TWI_RECEIVE_ACK); TWI_Transceiver_Busy(); // Wait until TWI is ready for next transmission. TWDR=0x00; //seconds address in table TWI(TWI_TRANSMIT); //transmit TWI(TWI_RECEIVE_ACK); TWI_Transceiver_Busy(); // Wait until TWI is ready for next transmission. TWI(TWI_RESTART); //restart TWDR=ds_address & 1; //target device address (ds1338) TWI(TWI_TRANSMIT); //transmit TWI_Transceiver_Busy(); // Wait until TWI is ready for next transmission. //twi(TWI_RECEIVE_ACK); //form ACK //sec=TWDR; //take byte of seconds ds1338 TWI(TWI_RECEIVE_NACK); //form NACK (don't need more data) sec = TWDR; //take last byte of seconds ds1338 TWI(TWI_STOP); //stop LCD4_cmd(0b00000010); LCD4Char(0b00110000 | (sec & 00001111)); LCD4Char(0b00110000 | (sec>>4)); _delay_ms(10000); } }
|
|