7 сегментный индикатор и странный глюк платы.
- Войдите на сайт для отправки комментариев
Сб, 01/09/2012 - 22:47
Здравствуйте. Подключил к Mega 2560 7 сегментный индикатор: земля на землю, аноды через 220 Ом резисторы на пины 22-28.
Написал говнокод:
// __2__
// | |
// 0 3
// | |
// ---1---
// | |
// 4 6
// | |
// --5--
int ind_pins[7] = {
22, 23, 24, 25, 26, 27, 28};
int ind_pins_count = 7;
int dig = 0;
void setup() {
for (int i=0; i<ind_pins_count; i++) {
pinMode(ind_pins[i], OUTPUT);
}
}
void seven_seg_digit_out(int pins_array[7], int digit) {
for (int i=0; i<ind_pins_count; i++) {
digitalWrite(pins_array[i], LOW);
}
if (digit == 0) {
digitalWrite(pins_array[0], HIGH);
digitalWrite(pins_array[2], HIGH);
digitalWrite(pins_array[3], HIGH);
digitalWrite(pins_array[4], HIGH);
digitalWrite(pins_array[5], HIGH);
digitalWrite(pins_array[6], HIGH);
}
...
if (digit == 8)
{
for (int i=0; i<ind_pins_count; i++) {
digitalWrite(pins_array[i], HIGH);
}
/*digitalWrite(pins_array[0], HIGH);
digitalWrite(pins_array[1], HIGH);
digitalWrite(pins_array[2], HIGH);
digitalWrite(pins_array[3], HIGH);
digitalWrite(pins_array[4], HIGH);
digitalWrite(pins_array[5], HIGH);
digitalWrite(pins_array[6], HIGH);
digitalWrite(pins_array[7], HIGH);*/
}
}
void loop() {
seven_seg_digit_out(ind_pins, dig);
dig++;
if (dig > 9) {
dig = 0;
}
delay (500);
}
Если я вывожу восьмёрку так, как показано сейчас, то всё нормально. Но если я убираю цикл и убираю комментирование с куска кода, то при выводе восьмёрки, начинает светится светодиод на 7 выводе. Он загорается и больше не гаснет. Если пропускать восьмёрку при выводе, то светодиод не загорается. Что не так?
ПОтому что в строке 49 вы вообще выпрыгнули за границы массива. Элемента pins_array[7] - не существует. То есть вы взяли случайное значение из памяти, посчитали его пином и включили этот пин.
Следующим, после массива, в памяти оказался "int ind_pins_count = 7;"
Вот эта семерка у вас и пошла "на выход" :)
И номера пинов лучше было сделать byte. Привыкайте память экономить.
А еще можно повеститься на пины одного порта, например PORTB (52,52,51,50,10,11,12,13)
Тогда можно будет без всяких циклов загать цифру одной коммандой
PORTB=0b11111111 // восьмерка
PORTB=0b11111101 // ноль.
Обязваить что-то типа массив
byte dgs[]={ 0x111111101 // 0 0x 11011011 // 1 ... 0x 11111111 // 8 };и зажигать нужную цифру так
А если не хочется с прямой записью в порт морочится или хочется сохранить возможность располагать пины как душа пожелает, или просто digitalWrite менее страшным кажется :), то
все-таки объявить dgs[] (сделать маски наших цифр. каждый по одному байту для каждой цифры, каждый бит этого байта означает какой сегменент нужное состояние сегмента)
и написать вашу функцию так:
void seven_seg_digit_out(int pins_array[7], byte digit) { for(byte i=7;i>=0;i--)digitalWrite(pins_array[i],bitRead(dgs[digit],i)); }Помоему так как-то компактней функция выглядит :)
ПОтому что в строке 49 вы вообще выпрыгнули за границы массива. Элемента pins_array[7] - не существует. То есть вы взяли случайное значение из памяти, посчитали его пином и включили этот пин.
Следующим, после массива, в памяти оказался "int ind_pins_count = 7;"
Вот эта семерка у вас и пошла "на выход" :)
Спасибо. Глупая ошибка :)