Мое оборудование в настоящее время имеет четыре набора датчиков, которые я рассматриваю как четыре отдельных последовательных порта с включенной только функцией приема, подключенной к младшим 4 битам порта 0. Я неоднократно пытался получить правильные данные последовательного порта (лазер прямо на датчик) безуспешно.Затем я исследовал, что для большей надежности на стандартном UART каждый бит дискретизируется с частотой 16x в секунду (я нашел это 3/4 вниз по странице на https://www.allaboutcircuits.com/technical-articles/back-to-basics-the-universal-asynchronous-receiver-transmitter-uart/).
, поэтому я в итоге выбрал свою собственную версиюиз-за моего времени, мой счет больше похож на 32x в секунду, но это нормально.
Я собираюсь объяснить, что я сделал первым, чтобы все поняли, что происходит.
объяснение кода
У меня есть четыре последовательных местоположения адресов, настроенных для указания значений счетчиков для каждого бита. Четыре бита считываются одновременно с аппаратного обеспечения, и счетчик для этого бита увеличивается или уменьшается на основеот того, установлен этот бит (свет обнаружен на этой группе датчиков) или сброшен (свет не обнаружен). Этот цикл часто выполняется со скоростью около 9600 бит / с.
Второй цикл выполняется только тогда, когда необходимо значение.Это происходит один раз каждые 16 раз, когда выполняется последний цикл (больше как на скорости 600 бит / с). Он принимает значение счетчика каждого бита, как если бы оно было числом со знаком ииспользует значение MSB в качестве окончательного значения этого бита.Эти значения MSB собираются вместе для формирования официального бита, считываемого с датчиков.
Можно ли использовать этот подход для надежного определения, установлено ли значение бита или сброшено?
И могу ли я как-нибудь повторить это?код, чтобы процессы работали быстрее?потому что каждый цикл потребляет большое количество тактов (от 32 до 40), и если я смогу уменьшить его до, может быть, 20 тактов, я был бы счастлив.
Кроме того, этот код выполняется на микроконтроллере AT89S52, поэтомуЯ использую его адреса расширенной памяти.
код
;memory is preinitialized to nulls
LAZMAJ equ 0E0h ;majority counters start address (end address at 0E4h)
MAJT equ 20h ;Majority value at bit address
mov A,P0 ;get bit values from hardware
mov R1,#LAZMAJ ;go to start of pointer
;loop uses 40 clock cycles out of 192 available
countmaj:
rrc A ;get bit
jnc noincmaj
inc @R1 ;bit is set so add 1 to counter for that bit
noincmaj:
jc incmaj
dec @R1 ;bit is clear so subtract 1 from counter for that bit
incmaj:
inc R1 ;move pointer to next bit
cjne R1,#LAZMAJ+4,countmaj ;see if pointer is out of range
;it is so end loop
;loop uses about 32 clock cycles and executes when we want data
mov R1,#LAZMAJ+4 ;go to out of range position
chkmaj:
dec R1 ;decrement pointer first so we are within range
mov MAJT,@R1 ;load value to majority variable. treat it as signed
mov @R1,#0h ;clear value from memory space
mov C,MAJT.7 ;Take sign and use that as carry
rlc A ;and put it into our final variable
cjne R1,#LAZMAJ,chkmaj ;if pointer isn't in first address then keep going
;otherwise exit loop and A=value we want