Пятница, 29.03.2024, 01:20
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Микроконтроллеры » Вопросы по МК » Часы на ATmega2560 (преобразование типов)
Часы на ATmega2560
ExpertonДата: Воскресенье, 09.01.2011, 18:04 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Помогите пожалуйста новичку!
Как разместить две переменные типа unsigned char, в одной переменной х
типа unsigned int.
Моя попытка сделать так:
x = (t.minute | t.hour<<8);
не увенчалась успехом.
Примечание: нужно, чтобы t.hour загрузился в старший байт 16-ти бит.
переменной х, а t.minute - соответственно в младший, для дальнейшего
BCD преобразования и вывода на 7-сегм. индикаторы.
Компилятор CVavr.
Заранее благодарен wacko
 
HiSERДата: Воскресенье, 09.01.2011, 20:40 | Сообщение # 2
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
3й предпочтительнее.

Code

//1:
x=((unsigned int)t.hour<<8)|t.minute;

//2:
#pragma warn-
unsigned int b2i(unsigned char a,unsigned char b) {
#asm
ld r31,y
ldd r30,y+1
#endasm
}
#pragma warn+

x=b2i(t.minute,t.hour);

//3:
union {
unsigned char a[2];
unsigned int b;
}x;

x.a[0]=t.minute;
x.a[1]=t.hour;

//x.b - unsigned int
 
ExpertonДата: Понедельник, 10.01.2011, 19:42 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
HiSER привет!
Извини погарячился, сказав что все работает -(
Точнее, секунды считает нормально, минуты тоже, но только до 59 мин.
Затем, как только в переменной t.hour появляется 1 (т.е прошел час),
на индикаторах появляется число 256 (т.е. наш сдвиг влево на 8),
затем 257,258 и т.д. Вообщем каждый час происходит инкремент на 256.
Глянь, пожалуйста, в чем косяк?

/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.9 Professional

Project : mega2560_Watch_sim5
Version : 0.05
Date : 04/01/2011
Author : F4CG
Company : F4CG
Comments:

Chip type : ATmega2560
Program type : Application
Clock frequency : 8.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 2048
*****************************************************/

#include <mega2560.h>
#include <mega2560_Watch_sim5.h>
#include <delay.h>

/* char not_leap(void);

char not_leap(void) //check for leap year
{
if (!(t.year%100))
return (char)(t.year%400);
else
return (char)(t.year%4);
} end of leap() */

typedef struct
{
unsigned char second; //enter the current time, date, month, and year
unsigned char minute;
unsigned char hour;
//unsigned char date;
//unsigned char month;
//unsigned int year;
}time;
time t;

flash unsigned char codes[10] = {0x05,0xdd,0x46,0x54,0x9c,0x34,0x24,0x5d,0x04,0x14};
static unsigned char data[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static unsigned int x = 0;


/* #pragma warn-
unsigned int b2i(unsigned char a,unsigned char b)
{
#asm
ld r31,y
ldd r30,y+1
#endasm
}
#pragma warn+*/

void convert_data (unsigned int x)
{
unsigned int temp,result;

temp = x;
result = temp/1000; //Calculate 1000-s
data[4]= codes[result];
temp = temp - result*1000;

result = temp/100; //Calculate 100-s
data[5]= codes[result];
temp = temp - result*100;

result = temp/10; //Calculaate 10-s
data[6]= codes[result];
temp = temp - result*10;

data[7]= codes[temp]; //Calculate 1-s

}//end of convert_data()

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
TCNT1H=0xE1;//E1
TCNT1L=0x7B;//7B
// Place your code here
//PORTC.2 = 1;
if (++t.second==60) //keep track of time, date, month, and year
{
t.second=0;
if (++t.minute==60)
{
t.minute=0;
if (++t.hour==24)
{
t.hour=0;
}
}
}//end if

x=((unsigned int)t.hour<<8)|t.minute;/////////////
//x = b2i(t.minute,t.hour);

}//end of interrupt(1)

// Timer 3 overflow interrupt service routine
interrupt [TIM3_OVF] void timer3_ovf_isr(void)
{
// Reinitialize Timer 3 value
TCNT3H=0xFB;//FB
TCNT3L=0xFB;//FB
// Place your code here
static unsigned char counter = 4;
PORTJ = 0x00;
PORTC = ~data[counter];
delay_us(150);//150us
if (counter == 4) PORTJ|=(1<<ANOD1);
if (counter == 5) PORTJ|=(1<<ANOD2);
if (counter == 6) PORTJ|=(1<<ANOD3);
if (counter == 7) PORTJ|=(1<<ANOD4);
counter++;
if (counter == 8) counter =4;

}//end of interrupt(3)

// Declare your global variables here
int main(void)
{
// Declare your local variables here
micro_init();
delay_ms(300);//300ms

// Global enable interrupts
#asm("sei")

while (1)
{
// Place your code here
convert_data(x); //Convert data to codes
delay_ms(5);//5ms

};//end while()

return 1;

}//end main

Симулирую в Протэусе 7.5
Спасибо! cranky

 
HiSERДата: Вторник, 11.01.2011, 07:38 | Сообщение # 4
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Не проще делать вот так?
Code

void convert_data (unsigned char hour,unsigned char minute) {
data[4]=codes[minute%10];
data[5]=codes[minute/10];
data[6]=codes[hour%10];
data[7]=codes[hour/10];
}

..............

convert_data(t.hour,t.minute);
 
ExpertonДата: Вторник, 11.01.2011, 09:47 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
HiSER привет! Конечно проще, а главное правильнее!!!!
Вот теперь точно все работает, как надо!!!!!
Я вчера ночью уже и сам стал понимать, что ошибка
в неверном BCD преобразовании - я отнесся к значениям
часов и минут, как к десятичным числам, т.е. кратным 10-ти,
анннет!-минуты надо было привязать к 60, а часы к 24.
Теперь, если можно, еще вопрос...
Как вывести моргание секундной точкой на месте dp сегмента
второго индикатора(единицы часов, ну чтобы отделить показания часов от минут).
Так как индикация динамическая,то у меня точки вспыхивают рядом со всеми индикаторами,
что не есть гуд=).
Спасибо большое за помощь.
 
HiSERДата: Вторник, 11.01.2011, 18:35 | Сообщение # 6
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
ставь бит в data[n] куда подключена точка.
 
ExpertonДата: Суббота, 09.07.2011, 08:52 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 4
Репутация: 0
Статус: Offline
Это снова Я )). Привет, HiSER! Точка горит и все как бы работает на УРА,
но хотелось бы,чтобы разделительная точка еще бы моргала с
частотой 1 сек, показывая ход часов.

/*
* my_Watch_01.c
*
* Created on: 30.06.2011
* Author: Vladimir

Chip type : ATmega128
Program type : Application
Clock frequency : 7.372800 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 2048
*****************************************************/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "my_Watch_01.h"

/* Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x11 ;PORTF
#endasm
#include <lcd.h>*/

typedef struct
{
unsigned char second; //enter the current time, date, month, and year
unsigned char minute;
unsigned char hour;
//unsigned char date;
//unsigned char month;
//unsigned int year;
}time;
time t;
// 0 1 2 3 4 5 6 7 8 9
unsigned char codes[10] = {0x05,0xdd,0x46,0x54,0x9c,0x34,0x24,0x5d,0x04,0x14};
static unsigned char data[4];

void convert_data (unsigned char hour,unsigned char minute)
{
data[3] = codes[minute%10];
data[2] = codes[minute/10];
data[1] = codes[hour%10];
data[1]&=~(1<<2);
data[0] = codes[hour/10];
}

// Timer 1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
// Reinitialize Timer 1 value
TCNT1H = 0xE3;//E1 per second for Proteus
TCNT1L = 0xE0;//7B per second for Proteus

// Place your code here
if (++t.second == 60) //keep track of time, date, month, and year
{
t.second = 0;
if (++t.minute == 60)
{
t.minute = 0;
if (++t.hour == 24)
{
t.hour = 0;
}
}
}//end if
}//end of interrupt(1)

// Timer 3 overflow interrupt service routine
ISR(TIMER3_OVF_vect)
{
// Reinitialize Timer 3 value(3.3ms => ~300Hz)
TCNT3H = 0xF4;//F4
TCNT3L = 0x1F;//1F
// Place your code here
static unsigned char counter = 0;
PORTG = 0x00;
PORTB = ~data[counter];
_delay_us(10); //150us
if (counter == 0) PORTG|=(1<<ANOD1);
if (counter == 1) PORTG|=(1<<ANOD2);
if (counter == 2) PORTG|=(1<<ANOD3);
if (counter == 3) PORTG|=(1<<ANOD4);
counter++;
if (counter == 4) counter = 0;

}//end of interrupt(3)

int main(void)
{
// Declare your local variables here
micro_init();

// Global enable interrupts
sei();

while (1)
{
// Place your code here

if ((~PINF)&(1<<PINF3)) // если нажата первая кнопка
{
_delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
//t.minute++; // к значению минуты добавляем еденицу
if (++t.minute == 60)
{
t.minute = 0;
}
}

if ((~PING)&(1<<PING4)) // если нажата вторая кнопка
{
_delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
//t.hour++; // к значению часов добавляем еденицу
if (++t.hour == 24)
{
t.hour = 0;
}

}//end if

convert_data(t.hour,t.minute); //Convert data to codes 7-segm. indicator's

_delay_ms(5);//5ms

};//end while()

return 1;

}//end of main

P.S. Сменил камень на ATmega128, кварц на 7,3728 мГц, и среду на Eclipse.
Заранее благодарен)
 
Форум » Микроконтроллеры » Вопросы по МК » Часы на ATmega2560 (преобразование типов)
  • Страница 1 из 1
  • 1
Поиск:

Хостинг от uCoz