Перейти к содержанию

Примеры кода для AVR


Duhas

Рекомендуемые сообщения

Добрый день!

Делаю динамическую индикацию на 7-ми сегментных индикаторах для Мега48 на три разряда.

Создал библиотеку с кодами цифр и пустым разрядом.

Также имеются две кнопки для увеличения / уменьшения счетчика на 1.

Все прошил и подключил работает отлично. Но возникла проблема с незначащими нулями перед числом (003 вместо 3).

В библиотеке прописал код пустого разряда. При тестировании этот разряд выключен, а остальные моргают в непредсказуемом порядке и показывают нули.

Я уже много способов перепробовал, чтобы убрать нули перед числом, но не получилось.

Ищу совета/помощи у более опятных программеров.

Привожу код моей программы и библиотеки.

#define F_CPU 4000000UL
#define NumberofButtons 2
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ButtonPress.h"
#include "seven_segment.h"
//========variables============
volatile int units=0;  //for counting the units of the CNT
volatile int tens=0;   //for counting the tens of the CNT
volatile int hundreds=0;  //for counting the hundreds of the CNT
volatile int Cathode=0;  //to define the cathode number
volatile char CNT=0;   //our counter to count the pressed UP and DOWN buttons
//==============================
int main(void)
{ DDRD=0xff;  //this port for LED segments
PORTD=0x00;  //in the beginning is nothing on the port
DDRC=0x07;  //this port for the Led cathodes
PORTC=0x00;  //in the beginning is nothing on the port
DDRB=0x00;  //this port for connecting of the counter pushbuttons
PORTB=0x03;  //pull-ups enable to the buttons
//=======Timer0_settings========
TCCR0A=(1<<WGM01);   //set CTC mode from datasheet
OCR0A=20;	 //calculated matched time 0.01sec from http://eleccelerator.com/avr-timer-calculator/ or from "Timer0_calc"
TIMSK0=(1<<OCIE0A);   //set the mask for our mode
sei();	  //enable the interrupts
TCCR0B=(1<<CS00)|(1<<CS02); //set prescaler clk/1024
   while(1)
   {  //*****************Buttons_procedures**********************************************
   if(ButtonPressed(0,PINB,0,250))  //if increment button is pressed
   {if(CNT<200)	   //verify that CNT less than 1000
 {CNT++;
 }
 else
 {CNT=200;	  //if CNT more than 999 then fix CNT to 999
 }
   }
   else
   {if(ButtonPressed(1,PINB,1,250)) //if decrement button is pressed
 {if(CNT>0)	  //verify that CNT more than 0
  {CNT--;
  }
  else
   {CNT=0;	  //if CNT less than 0 than fix CNT to 0
   }
 }
   }
   //***************CNT_segmentation_procedure**************************************
   hundreds=(CNT%1000)/100;
   tens=(CNT%100)/10;
   units=CNT%10;
   }
}
ISR(TIMER0_COMPA_vect)
{ //========variables=============
Cathode++;	   //increase the Cathode by one position
switch(Cathode)
{
 case 1:
  PORTC=(1<<Cathode);   //light next digit cathode
  PORTD=Segment(tens);  //out the tens
  break;
 case 2:
  PORTC=(1<<Cathode);   //light next digit cathode
  PORTD=Segment(units);  //out the units
  break;
 case 3:
  Cathode=0;
  PORTC=(1<<Cathode);   //light next digit cathode
  PORTD=Segment(hundreds); //out the hundreds
  break;
}
}

И библиотека кодов цифр:

int Segment( int Symbol)
{
switch(Symbol)
{
 case 0:
  return 0x3f; // "0"
 case 1:
  return 0x06; // "1"
 case 2:
  return 0x5b; // "2"
 case 3:
  return 0x4f; // "3"
 case 4:
  return 0x66; // "4"
 case 5:
  return 0x6d; // "5"
 case 6:
  return 0x7d; // "6"
 case 7:
  return 0x07; // "7"
 case 8:
  return 0x7f; // "8"
 case 9:
  return 0x6f; // "9"
 case 10:
  return 0x00; // " " empty space
}
return 0;
}

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Можете попробовать библиотеку из моей подписи или хотя бы посмотрите как это можно реализовать.

Удаление ведущих нулей можно сделать во время преобразования. Пара лишних тактов на условия ничто по сравнению с делениями.

hundreds=(CNT%1000)/100;

tens=(CNT%100)/10;
units=CNT%10;
if( hundreds == 0 ){
 hundreds = 10; //код пробела
 if( tens == 0 )tens = 10;
}

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Я пробовал, то что Вы предложили. К сожалению тот же самый результат.

Просмотрел Вашу библиотеку. Боюсь, мне понадобиться некоторое время чтобы разобраться до конца, что к чему.

В прерывании пробовал поставить числа и код пробела в PORTD=Segment(10); Все работало как надо. Как только возвращал назад переменные units, tens, hundreds проблема возвращалась.

Может я объявил неправильно переменные и счетчик CNT?

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

а остальные моргают в непредсказуемом порядке и показывают нули
Это всё потому, что Вы очень часто делаете преобразование в переменные tens, units и hundreds. Записанные в них нули, успевают вывестись в прерывании на индикатор ещё до того, как в них запишется код пустого символа. Отсюда и проскакивают нули на индикаторе.

По коду.

Функцию Segment можно заменить на массив констант. Будет и памяти меньше занимать и выполняться быстрее. И тип нужен не int, а uint_8 (аля - unsigned char).

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Пример кода для семисегментных индикаторов.

//========================================================================
#ifndef SEVEN_SEGM_LED_IND_H
#define SEVEN_SEGM_LED_IND_H
#include "seven_segm_led_ind.h"
//========================================================================
//========================================================================
#include "main_def_func.h"
//========================================================================
//========================================================================
#define ANODS_PORT		 PORTA
#define ANODS_PIN		 PINA
#define ANODS_DDR		 DDRA
//#define ANODS_2_PORT	 PORTA
//#define ANODS_2_PIN	 PINA
//#define ANODS_2_DDR	 DDRA
#define KATODS_PORT	 PORTC
#define KATODS_PIN		 PINC
#define KATODS_DDR		 DDRC
//========================================================================
//========================================================================
#define ANOD_1			 1<<2
#define ANOD_2			 1<<3
#define ANOD_3			 1<<4
#define ANOD_4			 1<<5
#define ANOD_5			 1<<6
#define ANOD_6			 1<<7
//------------------------------------------------------------------------
#define A				 1<<6
#define B				 1<<7 //	 A
#define C				 1<<3 // F B
#define D				 1<<2 //	 G
#define E				 1<<1 // E C
#define F				 1<<5 //	 D
#define G				 1<<4
#define H				 1<<0
//------------------------------------------------------------------------
#define ZERO			 (A | B | C | D | E | F)
#define ONE			 (B | C)
#define TWO			 (A | B | D | E | G)
#define THREE			 (A | B | C | D | G)
#define FOUR			 (B | C | F | G)
#define FIVE			 (A | C | D | F | G)
#define SIX			 (A | C | D | E | F | G)
#define SEVEN			 (A | B | C)
#define EIGHT			 (A | B | C | D | E | F | G)
#define NINE			 (A | B | C | D | F | G)
#define SPACE			 0
#define CHAR_SPACE		 10
//========================================================================
//========================================================================
#define MAX_LED_INDS	 6
#define ANODS_MASK		 (ANOD_1 | ANOD_2 | ANOD_3 | ANOD_4 | ANOD_5 | ANOD_6)
#define KATODS_MASK	 (A | B | C | D | E | F | G)
//========================================================================
//========================================================================
extern u08 dsp_buf [];
void clr_dsp_buf (void);
//========================================================================
//========================================================================
void _print_val_xxx (u08 x, u08 a);
#define print_val_xxx(x, a) _print_val_xxx(((x)-1), (a))
//========================================================================
//========================================================================
typedef struct index_anods
{
u08 i;
u08 anod;
} index_anods;
//========================================================================
//========================================================================
void set_proc_7_segm_ind_on (void);
void set_proc_7_segm_ind_off (void);
void proc_7_segm_ind (void);
//========================================================================
//========================================================================
#endif
//========================================================================

//========================================================================
#include "seven_segm_led_ind.h"
//========================================================================
//========================================================================
struct index_anods __flash tab_index_anods [] =
{
{0x01, ANOD_2},
{0x02, ANOD_3},
{0x03, ANOD_4},
{0x04, ANOD_5},
{0x05, ANOD_6},
{0x00, ANOD_1},
};
u08 __flash table_7_segm_char [11] =
{
ZERO, ONE,
TWO,	 THREE,
FOUR, FIVE,
SIX,	 SEVEN,
EIGHT, NINE,
SPACE,
};
//========================================================================
//========================================================================
soft_timer ST_PROC_7_SEGM_IND;
//------------------------------------------------------------------------
u08 dsp_buf [MAX_LED_INDS];
//------------------------------------------------------------------------
// Очистка буфера дисплея.
u08 dsp_buf [MAX_LED_INDS];
void clr_dsp_buf (void)
{
for (u08 i = 0; i < MAX_LED_INDS; i++)
 dsp_buf [i] = CHAR_SPACE;
}
//========================================================================
//========================================================================
void _print_val_xxx (u08 x, u08 a) // Вывод числа в формате xx,x.
{
char *ptr = num_str_buf + 7;

char_to_str (a);
dsp_buf[x] = *ptr; // Вывод сотен.
dsp_buf[x++];
ptr++;
dsp_buf[x] = *ptr;
dsp_buf[x++];
ptr++;
dsp_buf[x] = *ptr; // Вывод единиц.
}
//========================================================================
//========================================================================
static u08 _proc_7_segm_ind;
void set_proc_7_segm_ind_on (void)
{
_proc_7_segm_ind = 1;
}
void set_proc_7_segm_ind_off (void)
{
ANODS_DDR = 0;
ANODS_PORT = 0;
KATODS_DDR = 0;
_proc_7_segm_ind = 0;
}
void proc_7_segm_ind (void)
{
static u08 cnt_7_segm_ind;
switch (_proc_7_segm_ind)
{
 case 0:
	 break;
 case 1:
	 ANODS_DDR = 0xFF;
	 cnt_7_segm_ind = 0;
	 set_soft_timer (ST_PROC_7_SEGM_IND, 1, 1);
	 _proc_7_segm_ind = 2;
	 break;
 case 2:
	 if (handle_soft_timer (ST_PROC_7_SEGM_IND))
	 {
	 u08 cnt = cnt_7_segm_ind;
	 u08 anods;
	 u08 katods;
	 ANODS_PORT = 0;
	 KATODS_DDR = 0;
	 cnt_7_segm_ind = tab_index_anods [cnt].i;
	 anods = tab_index_anods [cnt].anod;
	 katods = table_7_segm_char [dsp_buf [cnt_7_segm_ind]];
	 ANODS_PORT = anods;
	 KATODS_DDR = katods;
	 }
	 break;
 default:
	 break;
}
}
//========================================================================

Пример программных таймеров.

//========================================================================
#ifndef SOFT_TIMERS_H
#define SOFT_TIMERS_H
#include "soft_timers.h"
#include "main_def_func.h"
//========================================================================
//========================================================================
#define ST_TCNT		 TCNT0
#define ST_TIMSK	 TIMSK
#define ST_OCIE		 OCIE0
#define ST_OCR		 OCR0
#define ST_TCCR		 TCCR0
#define CS0			 CS00
#define CS1			 CS01
#define CS2			 CS02
//========================================================================
//========================================================================
typedef struct soft_timer
{
bool status;
u08 sys_tick_prev;
u16 cnt;	 // Counter.
u16 period; // Period.
} soft_timer;
//========================================================================
//========================================================================
void init_soft_timers (void);
#define handle_soft_timer(a) _handle_soft_timer (&a)
bool _handle_soft_timer (void *ptr_timer);
#define set_soft_timer(a,b,c) _set_soft_timer (&a, b, c)
void _set_soft_timer (void *ptr_timer, u16 time, u16 period);
//========================================================================
#endif

//========================================================================
// Реализация программных таймеров.
// Примечание. Важно!!!!!!!!!!!!!!!
// При смене состояния конечного автомата нужно сбросить
// все таймеры, которые используются в этом состоянии. Иначе может быть
// следующая ситуация: если таймер уже использовался в
// текущем состоянии и флаг EN установлен, то по окончании времени
// выполнится соответствующий код.
//--------------------- Пример использования -----------------------------
// set_soft_timer (ST_LED_2_BLINK, 50, 50); // Установка таймера.
// if (handle_soft_timer (ST_LED_2_BLINK)) // Проверка таймера.
//========================================================================
//========================================================================
#include "soft_timers.h"
//========================================================================
//========================================================================
static u08 sys_tick;
//========================================================================
//========================================================================
#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0Comp(void)
{
ST_OCR += 250;
sys_tick++;
}
//========================================================================
//========================================================================
void init_soft_timers (void)
{
sys_tick = 0;
ST_TCNT = 0;
ST_OCR = 250;
ST_TCCR |= ((1<<CS0) | (1<<CS1));
set_bit (ST_TIMSK, ST_OCIE);
}
//------------------------------------------------------------------------
void _set_soft_timer (void *ptr_timer, u16 time, u16 period)
{
struct soft_timer *ptr = ptr_timer;
ptr -> status = true;
if (time == 0)
 ptr -> sys_tick_prev = ~sys_tick;
else
 ptr -> sys_tick_prev = sys_tick;
ptr -> cnt = time;
ptr -> period = period;
}
//------------------------------------------------------------------------
bool _handle_soft_timer (void *ptr_timer)
{
struct soft_timer *ptr = ptr_timer;
if (ptr -> status)
{
 if (ptr -> sys_tick_prev != sys_tick)
 {
	 ptr -> sys_tick_prev = sys_tick;
	 if (ptr -> cnt == 0)
	 {
	 if (ptr -> period != 0) ptr -> cnt = ptr -> period;
	 return true;
	 }
	 else
	 {
	 ptr -> cnt--;
	 if (ptr -> cnt == 0)
	 {
		 if (ptr -> period != 0) ptr -> cnt = ptr -> period;
		 return true;
	 }
	 }
 }
}
return false;
}
//========================================================================

Пример применения программных таймеров:

//************************************************************************
// Example of the using
//************************************************************************
soft_timer ST_LED_2_BLINK;
// Immediate execution
case 0:
set_soft_timer (ST_LED_2_BLINK, 0, 50);
break;
case 1:
if (handle_soft_timer (ST_PROC_NEC))
{
}
break;
// Execution after the specified time
case 0:
set_soft_timer (ST_LED_2_BLINK, 50, 50);
break;
case 1:
if (handle_soft_timer (ST_PROC_NEC))
{
}
break;
// Other
case 0:
set_soft_timer (ST_LED_2_BLINK, 1000, 50);
break;
case 1:
if (handle_soft_timer (ST_PROC_NEC))
{
}
break;

Изменено пользователем demiurg1978
Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

Привет всем.

Парни трудно ли написать код для тини с достаточным количеством портов чтобы она принимала сигнал с пульта NEC формата или RC5 и по сигналу с пульта управляла переключением реле.

Раньше ничего такого не делал, есть идея одну управляшку для ЦАПа сделать.

Изготовление заводских печатных плат.

http://forum.cxem.net/index.php?showtopic=141641&st=0

Ссылка на комментарий
Поделиться на другие сайты

Мои знания в написании кода равны 0

Но хочу попробовать сделать, на вскидку вроде должно быть не сложно.

Изменено пользователем Artik

Изготовление заводских печатных плат.

http://forum.cxem.net/index.php?showtopic=141641&st=0

Ссылка на комментарий
Поделиться на другие сайты

Ну так начните, станет ясно насколько это сложно лично для вас. Как обычно - выбор контроллера, чтение учебников, чтение даташита, написание мигалки диодами, а там видно будет.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Та да.

Я б к простому буту прилепил бы AES (в atxmega есть аппаратный модуль), но как полез разбираться... Атмеловцы какой то драйвер напридумали...

Так с ходу понял что атмеловцы по ходу с ума малеха посходили. По идее модулю должны были передаваться адреса памяти где лежат данные и ключ. И все. Но как оказалось там по факту что-то сильно замудрое нахреновертили. Как-то ненужно сильно сложно.

Изменено пользователем realm
Ссылка на комментарий
Поделиться на другие сайты

Если передавать функции данные и ключ открыто, считай нет никакого шифрования - всё это перехватывается и никакого толку от AES не будет - в таком случае проще использовать более простые методы шифрования типа DES.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

shads: Спасибо за ссылки. Буду разбираться.

 

3 часа назад, Alexeyslav сказал:

Если передавать функции данные и ключ открыто, считай нет никакого шифрования

Так оно внутри софта и так открыто передается.

С компа передавать вместе с данными ключи и т.д. - понятное дело смысл теряется.

Я имел в виду - загружаешь в модуль указатели в оперативку где лежат данные, ключ и т.д. И отправляешь модуль в свободное плавание. Ждешь когда выставится бит, что все готово да и все. Вот это по нормальному я считаю сделано. А так... полу программно, полу аппаратно еще и так, что черт ногу сломит. Какой тогда вообще смысл. Полностью программно ни чуть не хуже получается.

Изменено пользователем realm
Ссылка на комментарий
Поделиться на другие сайты

Вот это как раз подход тех кто ничерта не понимает в криптографии. Смысла в этой функции тогда никакого - отладчиком перехватывается ключ и считай нет никакого шифрования.

Весь этот программно-аппаратный комплекс создавался не только для вашей цели, а ещё с прицелом что среда исполнения кода может быть враждебной. Вам может и пофиг на утечку ключа, а кому-то очень даже не пофиг, когда файлы прошивки с программой-прошивальщиком высылаются клиенту для обновления прошивки, которую нельзя давать клиенту в открытом виде. Да он же распотрошит её в отладчике за 30 минут.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Не надо демогогий. Все что вы написали - это мимо.

На счет отладчика: А вот тут подробней. ATXmeg-у со всеми правильными лок битами можно выхватить через JTAG? Или в нагляк через него же загнать в 0 область свой софт (не снимая лок биты)?

Если возможность такая есть - она стремительно улетает нах... Я просто не в курсе...

Ссылка на комментарий
Поделиться на другие сайты

Товарищи, помоги разобраться с AVR315 по работе с i2c.

Почему в обработчике прерывания TWI нет никакой реакции на событие START? Как тогда начинается передача SLA+R/W :huh:

ISR (TWI_vect)
{
  static unsigned char TWI_bufPtr;
 
  switch (TWSR)
  {
    case TWI_START:             // START has been transmitted 
    case TWI_REP_START:         // Repeated START has been transmitted
      TWI_bufPtr = 0;                                     // Set buffer pointer to the TWI Address location
    case TWI_MTX_ADR_ACK: 
......
default:     
      TWI_state = TWSR;                                 // Store TWSR and automatically sets clears noErrors bit.
                                                        // Reset TWI Interface
      TWCR = (1<<TWEN)|                                 // Enable TWI-interface and release TWI pins
             (0<<TWIE)|(0<<TWINT)|                      // Disable Interupt
             (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|           // No Signal requests
             (0<<TWWC);  
}

 

Ссылка на комментарий
Поделиться на другие сайты

Вопрос к знатокам по CodevisionAVR.
В ATXmega32 есть модуль DES шифрования/дешифрования.
Все вроде просто - Записываем в регистры R0 ... R15 Данные и ключ, выставляем флаг, делаем команду DES и получаем в R0...R7 результат. Вот только загвостка есть. В хелпе CodevisionAVR написано, что регистры с 2 по 21 не доступны для ассемблерных вставок.
The registers R0, R1, R22, R23, R24, R25, R26, R27, R30 and R31 can be freely used in assembly routines.

Вопрос такой - Как собственно обойти это ограничение?

А если есть рабочий пример аппаратного DES для ATXmega под CodevisionAVR, было б вообще замечательно.

Изменено пользователем realm
Ссылка на комментарий
Поделиться на другие сайты

Здравствуйте всем!  напишите пожалуйста кто нибудь  примерно програму на языке си чтоб при включении питания на микроконтроллер загорелся светодиод а через 15с потух. CodeVisionAVR

Ссылка на комментарий
Поделиться на другие сайты

Привет всем! вот написал программу она только зажигает светодиод а не тушит через 15с, в  чем моя ошибка в программе.  кто может исправьте  ошибку   Спасибо.
#include <tiny13.h> 
#include <delay.h>

void main(void)
{

PORTB=0b111111;
DDRB=0b000001;

     while (1) { 
     
     
     PORTB.0=1;
     delay_ms(15000);
     PORTB.0=0;
    
};

   }

Изменено пользователем Коля 87
Ссылка на комментарий
Поделиться на другие сайты

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

Изменено пользователем DmitryS
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...