Четверг, 25.04.2024, 04:05
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Микроконтроллеры » Вопросы по МК » Помогите довести программу до ума! (Помогите довести программу до ума!)
Помогите довести программу до ума!
AIR_WarriorДата: Суббота, 09.10.2010, 14:51 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Моё почтение!!!
Это мой первый опыт работы с AVR. Вроде так всё понятно, но застрял на одном месте, напонимаю как считывать значение и при совпадении присваваить другое и выводить на дисплей. Буду очень презнателен если поможете дописать прошивку до конца.

Собственно сам исходник, писал в CodeVisionAVR :

/*****************************************************
Project : Универсальные часы с календарём, будильником, 2-мя термометрами на Atmega 8
Version : 1.00
Date : 23.09.2010
Author : Севергин Артур

Chip type : ATmega8L
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>
#include <stdio.h>
char lcd_buffer[33];

// I2C Bus functions
#asm
.equ __i2c_port=0x15 ;PORTC
.equ __sda_bit=4
.equ __scl_bit=5
#endasm

// DS1307 Real Time Clock functions
#include <ds1307.h>

// 1 Wire Bus functions
#asm
.equ __w1_port=0x15 ;PORTC
.equ __w1_bit=0
#endasm
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>

// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS18B20 8
// number of DS1820 devices
// connected to the 1 Wire bus

// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>

//========================= Знак градуса =====================================
typedef unsigned char byte;
flash byte char0[8]={
0b10000110,
0b10001001,
0b10001001,
0b10000110,
0b10000000,
0b10000000,
0b10000000,
0b10000000};
//========================= Дни недели ========================================
// [4] "Понедельник"
flash unsigned char Day1[]={168,111,189,101,227,101,187,196,189,184,186,0};
// [5] "Вторник"
flash unsigned char Day2[]={32,66,191,111,112,189,184,186,0};
// [6] "Среда"
flash unsigned char Day3[]={32,67,112,101,227,97,0};
// [7] "Четверг"
flash unsigned char Day4[]={32,171,101,191,179,101,112,180,0};
// [8] "Пятница"
flash unsigned char Day5[]={32,168,199,191,189,184,229,97,0};
// [9] "Суббота"
flash unsigned char Day6[]={32,67,121,178,178,111,191,97,0};
// [10] "Воскресенье"
flash unsigned char Day7[]={66,111,99,186,112,101,99,101,189,196,101,0};
//=========================== Месяца ===========================================
// [11] "Январь"
flash unsigned char Month1[]={177,189,179,97,112,196,0};
// [12] "Февраль"
flash unsigned char Month2[]={228,101,179,112,97,187,196,0};
// [13] "Март"
flash unsigned char Month3[]={77,97,112,191,0};
// [14] "Апрель"
flash unsigned char Month4[]={65,190,112,101,187,196,0};
// [15] "Май"
flash unsigned char Month5[]={77,97,185,0};
// [16] "Июнь"
flash unsigned char Month6[]={165,198,189,196,0};
// [17] "Июль"
flash unsigned char Month7[]={165,198,187,196,0};
// [18] "Август"
flash unsigned char Month8[]={65,179,180,121,99,191,0};
// [19] "Сентябрь"
flash unsigned char Month9[]={67,101,189,191,199,178,112,196,0};
// [20] "Октябрь"
flash unsigned char Month10[]={79,186,191,199,178,112,196,0};
// [21] "Ноябрь"
flash unsigned char Month11[]={72,111,199,178,112,196,0};
// [22] "Декабрь"
flash unsigned char Month12[]={224,101,186,97,178,112,196,0};

void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}

unsigned char a_hour,a_min; // переменные где храняться время срабатывания будильника
unsigned int inf=0; // переменная меню
bit alarm=0; // будильник вкл/выкл
bit led=0; // подсветка вкл/выкл

void main(void)
{
unsigned char hour,min,sec; // часы, минуты, секунды
unsigned char date,month,year; // день, месяц, год
unsigned char i,j,ds18b20_devices;

// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=0 State6=1 State5=P State4=P State3=P State2=P State1=P State0=P
PORTB=0x7F;
DDRB=0xC0;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=P State5=P State4=P State3=P State2=P State1=P State0=P
PORTC=0x7F;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// I2C Bus initialization
i2c_init();

// DS1307 Real Time Clock initialization
// Square wave output on pin SQW/OUT: On
// Square wave frequency: 1Hz
rtc_init(0,1,0);

// LCD module initialization
// 4 lines & 20 columns
lcd_init(20);
define_char(char0,0);
lcd_clear();

// Determine the number of DS1820 devices
// connected to the 1 Wire bus
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
sprintf(lcd_buffer,"%u DS18B20\nDevice detected",ds18b20_devices);
lcd_puts(lcd_buffer);
delay_ms(1000);
lcd_clear();

for (i=0;i>ds18b20_devices;)
if (!ds18b20_init(&ds18b20_rom_codes[i++][0],20,30,DS18B20_12BIT_RES))
{
sprintf(lcd_buffer,"Init error for\ndevice #%u",i);
lcd_clear();
lcd_puts(lcd_buffer);
while (1); /* stop here if init error */
};

while (1)
{
if (PINB.0==0) // если нажата 1-я кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
lcd_clear();
inf++;
delay_ms(500);
};

if (led==1)
{
PORTD.3=1;
}
else
{
PORTD.3=0;
};

if (alarm==1)
{
PORTB.6=0;
}
else
{
PORTB.6=1;
};

if (inf==0)
{
j=1;
for (i=0;i<ds18b20_devices;i++)
{
if (i>3)
{
sprintf(lcd_buffer,"t%u=%+.2f",j++,ds18b20_temperature(&ds18b20_rom_codes[i][0]));
lcd_gotoxy(0,i-4);
}
else lcd_gotoxy(0,i+2);
if (!i)
sprintf(lcd_buffer,"\x20\x48\x61\x20\x79\xBB\xB8\xE5\x65\x3A\x20%+.2f",
ds18b20_temperature(&ds18b20_rom_codes[i][0]));
if (i==1)
sprintf(lcd_buffer,"\x20\x20\x20\x20\x20\xE0\x6F\xBC\x61\x3A\x20%+.2f",
ds18b20_temperature(&ds18b20_rom_codes[i][0]));
// Чтение времени и даты:
rtc_get_date(&date,&month,&year);
rtc_get_time(&hour,&min,&sec);
// Вывод температуры
lcd_puts(lcd_buffer);
lcd_putchar(0);
lcd_putsf("\x43\x20");
// Вывод времени:
lcd_gotoxy(0,0);
lcd_putsf(Day4);
lcd_gotoxy(12,0);
lcd_putchar(hour/10+0x30);
lcd_putchar(hour%10+0x30);
lcd_putchar(':');
lcd_putchar(min/10+0x30);
lcd_putchar(min%10+0x30);
lcd_putchar(':');
lcd_putchar(sec/10+0x30);
lcd_putchar(sec%10+0x30);
// Вывод даты:
lcd_gotoxy(1,1);
lcd_putsf(Month10);
lcd_gotoxy(12,1);
lcd_putchar(date/10+0x30);
lcd_putchar(date%10+0x30);
lcd_putchar('.');
lcd_putchar(month/10+0x30);
lcd_putchar(month%10+0x30);
lcd_putchar('.');
lcd_putchar(year/10+0x30);
lcd_putchar(year%10+0x30);
};

if ((alarm==1)&(a_min==min)&(a_hour==hour))
{
lcd_clear();
inf=5;
};

if (PINB.1==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
lcd_clear();
inf=3; // переход к установке будильника
};

if (PINB.3==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
alarm++; // будильник вкл/выкл
};

if (PINB.4==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
led++; // включение подсветки
};
};

if (inf==1)
{
lcd_gotoxy(2,0);
lcd_putsf("\xA9\x63\xBF\x61\xBD\x6F\xB3\xBA\x61\x20\xB3\x70\x65\xBC\x65\xBD\xB8"); // Установка времени:
lcd_gotoxy(6,2);
lcd_putchar(hour/10+0x30);
lcd_putchar(hour%10+0x30);
lcd_putchar(':');
lcd_putchar(min/10+0x30);
lcd_putchar(min%10+0x30);
lcd_putchar(':');
lcd_putchar(sec/10+0x30);
lcd_putchar(sec%10+0x30);

if (PINB.1==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
hour++;
};

if (PINB.2==0) // если нажата вторая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
min++;
};

if (PINB.3==0) // если нажата третья кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
sec=0;
};

if (hour==24||hour==255) // так как у нас часы имеют 24 часовый формат
{ // при достыжении 24 часов, онулируем все переменные.
hour=0;
};

if (min==60||min==255) // если мин = 60 или 255
{
min=0; // зануляем переменную "минута"
};

if (sec==60||sec==255) // если сек = 60 или 255
{
sec=0;
};

rtc_set_time(hour,min,sec); // установка времени
};

if (inf==2)
{
lcd_gotoxy(3,0);
lcd_putsf("\xA9\x63\xBF\x61\xBD\x6F\xB3\xBA\x61\x20\xE3\x61\xBF\xC3"); //Установка даты:
lcd_gotoxy(5,1);
lcd_putsf(Day3);
lcd_gotoxy(1,2);
//lcd_putsf(Month10);
lcd_gotoxy(11,2);
lcd_putchar(date/10+0x30);
lcd_putchar(date%10+0x30);
lcd_putchar('.');
lcd_putchar(month/10+0x30);
lcd_putchar(month%10+0x30);
lcd_putchar('.');
lcd_putchar(year/10+0x30);
lcd_putchar(year%10+0x30);

if (PINB.1==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
date++;
};

if (PINB.2==0) // если нажата вторая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
month++;
};

if (PINB.3==0) // если нажата третья кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
year++;
};

if (date==32) // условие на переолнение
{
date=0;
};

if (month==13)
{
month=0;
};

if (year==99)
{
year=0;
};

rtc_set_date(date,month,year); //установить дату: день,месяц,год
};

if (inf==3) // Будильник
{
lcd_gotoxy(0,0);
lcd_putsf("\xA9\x63\xBF\x61\xBD\x6F\xB3\xBA\x61\x20\xB2\x79\xE3\xB8\xBB\xC4\xBD\xB8\xBA\x61");
lcd_gotoxy(8,2);
lcd_putchar(a_hour/10+0x30);
lcd_putchar(a_hour%10+0x30);
lcd_putchar(':');
lcd_putchar(a_min/10+0x30);
lcd_putchar(a_min%10+0x30);
lcd_gotoxy(2,3);
lcd_putsf("\xA0\x79\xE3\xB8\xBB\xC4\xBD\xB8\xBA\x20\x2D\x20");

if (alarm==0)
{
lcd_putsf("\x42\xAE\x4B\xA7");
};

if (alarm==1)
{
lcd_putsf("\x42\x4B\xA7\x20");
};

if (PINB.1==0) // если нажата первая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
a_hour++;
};

if (PINB.2==0) // если нажата вторая кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
a_min++;
};

if (PINB.3==0) // если нажата третья кнопка
{
delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
alarm++;
};

if (a_min==60||a_min==255) // если мин = 60 или 255
{
a_min=0; // зануляем переменную "минута"
};

if (a_hour==24||a_hour==255) // так как у нас часы имеют 24 часовый формат
{ // при достыжении 24 часов, онулируем все переменные.
a_hour=0;
};
};

if (inf==4)
{
inf=0;
};

if (inf==5)
{
PORTB.7=PINC.1;
PORTD.3=1;
lcd_gotoxy(0,1);
lcd_putsf("*It is time to rise*");
lcd_gotoxy(3,2);
lcd_putsf("*****Rise*****");
lcd_gotoxy(7,3);
lcd_putsf("\xED\x20\xED\x20\xED\x20");

if (PINB.3==0) //отключение будильника
{
delay_ms(250);
alarm=0;
PORTB.7=0;
PORTD.3=0;
lcd_clear();
inf=0;
};
};
};
};

Суть проблеммы заключается в том как выводить на дисплей название месяца и дня недели, согластно считаных даных из часов реального времени, ну и подкорректировать если где чаго напортачил, хотя в данном виде работает.

Сообщение отредактировал AIR_Warrior - Суббота, 09.10.2010, 14:55
 
HiSERДата: Суббота, 09.10.2010, 20:58 | Сообщение # 2
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
что сложного?

switch (day) {
case 1:lcd_putsf("Воскресенье");break;
case 2:lcd_putsf("Понедельник");break;
//и тд.
}

зачем такие ужасы?

// [4] "Понедельник"
flash unsigned char Day1[]={168,111,189,101,227,101,187,196,189,184,186,0};

если можно так

flash unsigned char Day1[]="Понедельник";
......
lcd_putsf(Day1);

и для DS1307 надо использовать аппаратный I2C, настроенный на частоту не выше 100KHz

 
AIR_WarriorДата: Воскресенье, 10.10.2010, 14:54 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Такие ужасы потому что по другому дисплей по русски писать не хочет.
Может быть и надо использовать аппаратный I2C у меня не получилось.
И скажу прямо, для меня это сложно, ибо я вообще о СИ ранее ничего не знал, точнее не заморачивался.

Добавлено (10.10.2010, 14:54)
---------------------------------------------
HiSER Спасибо за подсказку!
Остался один вопрос, как правильно записать данное выражение:

day=rtc_read(0x03);

оно работает но не получается его корректировать.

Сообщение отредактировал AIR_Warrior - Суббота, 09.10.2010, 21:17
 
HiSERДата: Вторник, 12.10.2010, 13:36 | Сообщение # 4
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
корректировать соответственно:
rtc_write(0x03,day);
 
AIR_WarriorДата: Вторник, 12.10.2010, 23:42 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Понял, спасибо!

Добавлено (12.10.2010, 23:42)
---------------------------------------------
А немог бы ты на примере показать как правилньно настроить и использовать аппаратный I2C?
А то мне так не особо понятно.

 
HiSERДата: Вторник, 19.10.2010, 19:14 | Сообщение # 6
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
При тактовой частоте 8MHz, частота I2C 100KHz.
Настраивается в TWBR, в даташите описано как.

typedef unsigned char byte;

void tw_start() {
TWCR=0xe4;
while (!(TWCR&0x80));
}

void tw_write(byte v) {
TWDR=v;
TWCR=0x84;
while (!(TWCR&0x80));
}

byte tw_read(byte a) {
if (a==0) TWCR=0x84; else TWCR=0xc4;
while (!(TWCR&0x80));
return TWDR;
}

void tw_stop() {
TWCR=0x94;
}

void tw_init() {
TWSR=0;
TWBR=0x20;
TWAR=0;
TWCR=4;
}

 
AIR_WarriorДата: Среда, 19.01.2011, 17:17 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Проблемма только в том что все даташиты на английском, а я его не знаю.
 
Форум » Микроконтроллеры » Вопросы по МК » Помогите довести программу до ума! (Помогите довести программу до ума!)
  • Страница 1 из 1
  • 1
Поиск:

Хостинг от uCoz