От нечего делать (вернее от нежелания побороть лень) накидал показательный вариант индикатора уровня по последнему обсуждению. Это только заготовка, болванка. К сожалению дальнейшее написание требует наличия железа, т.к. Протеус почему-то не хочет симулировать обе линейки светодиодов, ошибку выдает. Плюс отсутствие АЦП и в 12 раз медленнее по сравнению с STC15 (АТ89С51 все-таки старик), приходится в программе константы подделывать.
Может автор вопроса пожелает дополнить самостоятельно. Или кто-то другой допишет привязку уровней входных сигналов (они уже измеряются) к индексу матрицы. Ну и кнопку еще надо обработать.
Здравствуйте. Помогите с решением задачи. Считать с параллельного порта байт данных (двоично-десятичный код), на одноразрядный семисегментный индикатор вывести сумму тетрад, если результат больше числа 9, на индикатор вывести "0". Заранее спасибо.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
СТУДЕНТ... давненько я с 51-й не практиковал... примерно так:
Код:
mov r7,port_n ; читаем порт в буфер mov a,#0x0F ; маска младшей тетрады в АСС anl a,r7 ; выделяем младшую тетраду xch a,r7 ; исходный код в АСС, мл. тетрада в r7 anl a,#0xF0 ; выделяем старшую тетраду swap a ; разворот тетрад add a,r7 ; сложили da a ; десятичная коррекция при сложении (поставит АС=1 при переносе ; в старшую тетраду jnb AC,pt_0 ; анализ результата clr a ; если результат более 9 сброс АСС в 0 pt_0: inc a movc a,@a+pc ; позиция +1 байт - обход команды ret ret ; возврат из подпрограммы обработки segment_table: .db ....... ; генератор сегментной комбинации
Всем привет! Начинаю осваивать AT89C51 (заставляют в институте ) Программирую на C, установил Keil.
Подскажите пожалуйста, как мне запустить таймер, длительностью скажем, 1мс (кварц,допустим, 12мгц). И при его переполнении выполнять какой-то код? Годной инфы не нашел, а где нашел - как-то слишком мудрено все расписано и сделать мне это не получается.
_________________ — Да не боись, всего двенадцать вольт… и восемьсот ампер.
.. (заставляют в институте ) .. .. Годной инфы не нашел, а где нашел - как-то слишком мудрено ...
Раз не можете понять, как выполнять подпрограмму по переполнению таймера, и вообще настроить таймер - то лучше увольтесь из института - и никто не будет заставлять.
Подсказывают тем, кто сам хоть что-нибудь пытается понять и сделать - Вы пытались ? Если утверждаете, что пытались, то поведайте нам, что Вы уже знаете о таймерах м.к. и прерываниях (, а пустословию место или в "МЯУ!" или в "Сделайте за меня задание" - там за $ помогают .. )
_________________ < виртуальная "кнопочка" >--( WWW ) <- Убедительная просьба интересующимся старыми компьютерами типа РК86 - не пишите в теме в барахолке, пишите Ваши вопросы в ( лс ) пожалуйста
Ну опять же, там в основном теория, принцип работы - это я примерно знаю. А примеры кода на асме.
Добавлено after 11 minutes 11 seconds:
petrenko писал(а):
Раз не можете понять, как выполнять подпрограмму по переполнению таймера, и вообще настроить таймер - то лучше увольтесь из института - и никто не будет заставлять.
Подсказывают тем, кто сам хоть что-нибудь пытается понять и сделать - Вы пытались ? Если утверждаете, что пытались, то поведайте нам, что Вы уже знаете о таймерах м.к. и прерываниях (, а пустословию место или в "МЯУ!" или в "Сделайте за меня задание" - там за $ помогают .. )
Да ладно вам. задание куда сложнее, а учить этому меня будут только ближе к лету. Имел небольшой опыт с авр, вот и взялся попробовать. ладно, не буду разглагольствовать.
вот инициализация прерывающей процедуры:
Код:
void mProcIntT0 () interrupt TF0_VECTOR { TR0 = 0; // Останов таймера. TH0 = ~mKodTime >>8; // Загрузка на отсчет TL0 = ~mKodTime;// заданного времени. TR0 = 1; // Пуск таймера. mFlagTik =1; // Установка флажка тиков. mCountTik++; // Счет системных“тиков”. // Здесь при необходимости можно выполнять и другие действия. }
Процедуру нужно вызывать в самом начале программы, ведь так?
Код:
void main(void) { mProcIntT0(); ... }
Но тогда Keil не компилирует код, выдавая мне ошибку
Код:
kursach.c(52): error C205: can't call an interrupt function
Добавлено after 6 minutes 10 seconds: еще небольшой вопрос по кейлу. учитывая, что процессор выполняет каждую команду за 12 тактов, то на частоте в 12 мгц каждая команда выполняется за 1мкс.
в книге предлагается такой макрос: #definemDelay1mks {_asm nop _endasm;} кейл _asm не понимает. понимает он #pragma asm, но таким макаром макрос с нопами не написать. Это можно реализовать как-то иначе?
_________________ — Да не боись, всего двенадцать вольт… и восемьсот ампер.
Последний раз редактировалось WaL97 Вс фев 12, 2017 10:09:36, всего редактировалось 1 раз.
В принципе... примеры можно подчерпнуть из документации к китайским STC15xxxxxxx... В отношении примеров для программирования это своеобразные учебники. То же касается и описания синтаксиса и директив компиляторов ассемблера и СИ в спецразделе в конце каждого даташита. К примеру вот тут:
Я не знаю особенности AT89C51, но STC по сравнению с классическим 8051 работает несколько иначе, начиная от однотактных команд, и заканчивая иным режимом 0 таймера (16 бит), если ограничиться тактированием.
В часах я делал инициализацию Т0 так: Спойлер
Код:
void t0set(void) { // Timer0 @ 11.0592Mhz /\ 0.0904us*12(PSC)*256*18=5ms - Led display refresh period // 0xEE до 00 тикает 18 раз, т.е. 16-разрядный счетчик 0хЕЕ00 будет тикать до переполнения 4608 раз. // ВАЖНО: // После каждого переполнения пары (THx:TLx) в соответствии с заданным режимом работы (Mode 0) // регистры TLх и THх будут автоматически заряжаться до указанных значений из "зеркальных" // регистров RL_TLx и RL_THx. При остановленном таймере (TRх = 0) запись в TLх и THх автоматически // запишет те же значения и в регистры RL_TLx и RL_THx. // Если же таймер запущен (TRx = 1), запись в TLх и THх изменит // значения ТОЛЬКО "зеркальных" регистров RL_TLx и RL_THx. TMOD = 0; // T0 and T1 both 16-bit auto-reload timer mode AUXR = 0; // T0 and T1 uses SysClk/12 (8051 compatibility mode). INT_CLKO = 0; TL0 = 0; TH0 = 0xEE; // 18*256=4608 TF0 = 0; // Clear T0 interrupt flag, TCON,5 TR0 = 1; // Timer0 start, TCON,4 ET0 = 1; // Enable Timer0 interrupt }
А прерывание вообще никаких остановок и перезагрузок не требует. Таймер при переполнении сам загружает начальные значения из "зеркальных" регистров в основные и начинает считать. Спойлер
Код:
void timer0_isr (void) interrupt 1 using 1 { //******************************************** // В прерывание по Т0 мы попадаем каждые 5 мс. //********************************************
//******** Вывод на индикатор ******** anode |= 0x3C; // Р3[5:2] - set anode pins to switch off LEDs cathode = filldisplay(row, digit, Led[row][digit]); // Преобразование числа в символ индикатора dbuf. anode &= ~(1 << (digit + 2)); // Включаем разряд. if (++digit > 3) digit = 0; // Следующий разряд. if (abc_ena) t1set(); // Если автояркость активна, запускаем таймер для псевдо-ШИМ: } // End of T0 interrupt
Это работает в Keil. Пересчитайте под свои потребности. С такими комментариями и наличии ДШ разобраться будет легко.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Zhuk72 Спасибо! Сейчас глупый вопрос конечно же, но... вот я объявляю эти две функции
Код:
void t0set(void) {
}
Код:
void timer0_isr (void) interrupt 1 using 1 {
}
затем идет основная
Код:
void main(void) { while(1) {
} }
в какой части и как мы их должны вызвать? Спрашиваю, чтоб знать, что хотя бы в этом не накосячить и разбираться только с инициализацией таймера\прерываний
_________________ — Да не боись, всего двенадцать вольт… и восемьсот ампер.
Прерывания в теле программы не вызывают, поэтому и объявлять не требуется. Вызвать настройку таймера нужно тогда, когда он должен начать работу, например в main, так:
Код:
t0set();
Кроме того, чтобы работали прерывания, их нужно глобально разрешить.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
в asm нет ничего плохого, особенно в условиях ограниченных ресурсов. А 89С51 поддерживается Вашим компилятором?
Дело в том, что хотелось бы понимать, что делает каждая строка в коде. А всю программу написать на ассемблере уж точно не смогу. Поэтому использую си. Мой любимый cvAVR х51 контроллеры не поддерживает, после гуглений нашел Keil C51. подключаю at89x51.h, затем портами управлять у меня получается. Так что наверное да, поддерживается
Update Всем спасибо! Удалось реализовать! Наконец порт "замигал". Дальше уже все что нужно сделаем.
_________________ — Да не боись, всего двенадцать вольт… и восемьсот ампер.
Для 51-й или кейл или SDCC где-то отсюда ссыль была: http://stcmicro.com/rjxz.html есть правда еще производители софта... да уж там больно "платные" IDE...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 31
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения