|
|
  |
Не работает корректно операция << в (*указатель |= (1<<pin)) IAR AVR, в железе не работает |
|
|
|
Nov 26 2008, 12:46
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
На портах висят датчики температуры DS18S20 у ATmega640. Код в IAR AVR. Если работать с битами портов по варианту 1, где операция сдвига осуществляется при выполнении операции, то с выводов мы всегда считываем 0xFF. Если работать по варианту 2, где переменной pin сразу присваивается сдвинутый номер вывода, и внутри подпрограмм сдвига в операциях над портами нет, то всё замечательно работает со всеми датчиками температуры. Ещё одна особенность в варианте 1, если на любом порте работаем с датчиком на PIN0, то они нормально опрашиваются. В симуляторе багов не заметил, и он показывает что нормально управляет ножками портов как в варианте 1 так и 2. Вариант 1: Код ptr_dport = (uchar*)&DDRD; ptr_pin = (uchar*)&PIND; pin = PD1;
*ptr_dport |= (1<<pin); //0 на линии *ptr_dport &= ~(1<<pin);//1 на линии Вариант 2: Код ptr_dport = (uchar*)&DDRD; ptr_pin = (uchar*)&PIND; pin = 1<<PD1;
*ptr_dport |= pin; //0 на линии *ptr_dport &= ~pin; //1 на линии
|
|
|
|
|
Nov 26 2008, 13:20
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
Цитата(Сергей Борщ @ Nov 26 2008, 18:08)  Показывайте, как объявлена ptr_dport. unsigned char *ptr_dport, *ptr_pin, pin; //указатели порта и пина, к которому подключен датчик
|
|
|
|
|
Nov 26 2008, 13:30
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
Цитата(MrYuran @ Nov 26 2008, 18:23)  Второй вариант лучше. Меньше операций. Нет бестолковых сдвигов, так как 1<<pin будет вычисляться, а 1<<DP1 подставит препроцессор (я так понимаю DP1 объявлено через #define) То что лучше я уже понял  и поменяю, но, я хочу понять и разобраться, почему не работает 1й вариант.
|
|
|
|
|
Nov 26 2008, 14:17
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(SZ0 @ Nov 26 2008, 17:30)  То что лучше я уже понял  и поменяю, но, я хочу понять и разобраться, почему не работает 1й вариант. Оптимизатор решил, что это dead assignment. Правильно так: Код unsigned char volatile * ptr_dport;
|
|
|
|
|
Nov 26 2008, 15:09
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
Цитата(Сергей Борщ @ Nov 26 2008, 19:36)  Совершенно верно. И не понадобятся лишние приведения типа ptr_dport = (uchar*). Причем без volatile при другом положении звезд на небе не будет работать и второй вариант. Спасибо! 1й вариант так и не заработал с изменениями. Поэтому ввёл изменения во 2м добавив volatile. А как было определено Цитата Оптимизатор решил, что это dead assignment. ?
|
|
|
|
|
Nov 26 2008, 15:49
|
Местный
  
Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031

|
Цитата(SZ0 @ Nov 26 2008, 15:46)  В симуляторе багов не заметил, и он показывает что нормально управляет ножками портов как в варианте 1 так и 2. Вообще в таких случаях лучше анализировать ассемблерный листинг, а не гадать на кофейной гуще. Есть ещё один сомнительный момент во всей вашей программе Неизвестно что записано в PORTD! Если там 0, то тогда внутренние подтяжки выключены и когда в DDRD пишется ноль контроллер вообще не управляет линией. Цитата Если работать по варианту 2, где переменной pin сразу присваивается сдвинутый номер вывода Всё таки у вас pin это переменная, а не константа, т.ч. по поводу сразу вы явно погорячились. Вобщем смотрите ассемблерный листинг и нам покажите авось сразу разберёмся, что к чему
|
|
|
|
|
Nov 28 2008, 09:13
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
Цитата(_Sam_ @ Nov 26 2008, 20:49)  Есть ещё один сомнительный момент во всей вашей программе Неизвестно что записано в PORTD! Если там 0, то тогда внутренние подтяжки выключены и когда в DDRD пишется ноль контроллер вообще не управляет линией. Вобщем смотрите ассемблерный листинг и нам покажите авось сразу разберёмся, что к чему  Резисторы подтяжки внешние. Листинг подготовлю и выложу чуть позже.
|
|
|
|
|
Dec 4 2008, 18:17
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 14-02-06
Пользователь №: 14 331

|
листинг кода: Вариант 1: не работает с датчиками на всех выводах, кроме на 0 PIN Код unsigned char *ptr_dport, *ptr_pin; unsigned char pin;
ptr_dport = (uchar*)&DDRD; ptr_pin = (uchar*)&PIND; pin = PD1;
*ptr_dport |= (1<<pin); //0 на линии
\ 00000004 9140.... LDS R20, pin \ 00000008 E001 LDI R16, 1 \ 0000000A E010 LDI R17, 0 \ 0000000C ........ CALL ?S_SHL_L02 \ 00000010 .... LDI R30, LOW(ptr_dport) \ 00000012 .... LDI R31, (ptr_dport) >> 8 \ 00000014 81A0 LD R26, Z \ 00000016 81B1 LDD R27, Z+1 \ 00000018 911C LD R17, X \ 0000001A 2B10 OR R17, R16 \ 0000001C 931C ST X, R17
*ptr_dport &= ~(1<<pin);//1 на линии
\ 0000002C 9140.... LDS R20, pin \ 00000030 E001 LDI R16, 1 \ 00000032 E010 LDI R17, 0 \ 00000034 ........ CALL ?S_SHL_L02 \ 00000038 9500 COM R16 \ 0000003A .... LDI R30, LOW(ptr_dport) \ 0000003C .... LDI R31, (ptr_dport) >> 8 \ 0000003E 81A0 LD R26, Z \ 00000040 81B1 LDD R27, Z+1 \ 00000042 911C LD R17, X \ 00000044 2310 AND R17, R16 \ 00000046 931C ST X, R17
?S_SHL_L02: dec r20 brmi 0x2AA lsl r16 rol r17 rjmp ?S_SHL_L02 ret Вариант 1 исправленный: так же не работает Код volatile unsigned char *ptr_dport, *ptr_pin; unsigned char pin;
ptr_dport = &DDRD; ptr_pin = &PIND; pin = PD1;
*ptr_dport |= (1<<pin); //0 на линии
\ 00000004 9140.... LDS R20, pin \ 00000008 E001 LDI R16, 1 \ 0000000A E010 LDI R17, 0 \ 0000000C ........ CALL ?S_SHL_L02 \ 00000010 2F30 MOV R19, R16 \ 00000012 .... LDI R30, LOW(ptr_dport) \ 00000014 .... LDI R31, (ptr_dport) >> 8 \ 00000016 8100 LD R16, Z \ 00000018 8111 LDD R17, Z+1 \ 0000001A 01F8 MOVW R31:R30, R17:R16 \ 0000001C 8100 LD R16, Z \ 0000001E 2B03 OR R16, R19 \ 00000020 8300 ST Z, R16
*ptr_dport &= ~(1<<pin);//1 на линии
\ 00000030 9140.... LDS R20, pin \ 00000034 E001 LDI R16, 1 \ 00000036 E010 LDI R17, 0 \ 00000038 ........ CALL ?S_SHL_L02 \ 0000003C 9500 COM R16 \ 0000003E .... LDI R26, LOW(ptr_dport) \ 00000040 .... LDI R27, (ptr_dport) >> 8 \ 00000042 91ED LD R30, X+ \ 00000044 91FC LD R31, X \ 00000046 9711 SBIW R27:R26, 1 \ 00000048 8110 LD R17, Z \ 0000004A 2310 AND R17, R16 \ 0000004C 8310 ST Z, R17 Вариант 2: работает, без volatile сказали что может и не заработать Код unsigned char *ptr_dport, *ptr_pin; unsigned char pin;
ptr_dport = (uchar*)&DDRD; ptr_pin = (uchar*)&PIND; pin = 1<<PD1;
*ptr_dport |= pin; //0 на линии
\ 00000002 9110.... LDS R17, pin \ 00000006 .... LDI R30, LOW(ptr_dport) \ 00000008 .... LDI R31, (ptr_dport) >> 8 \ 0000000A 81A0 LD R26, Z \ 0000000C 81B1 LDD R27, Z+1 \ 0000000E 912C LD R18, X \ 00000010 2B21 OR R18, R17 \ 00000012 932C ST X, R18
*ptr_dport &= ~pin; //1 на линии
\ 00000022 9110.... LDS R17, pin \ 00000026 9510 COM R17 \ 00000028 .... LDI R30, LOW(ptr_dport) \ 0000002A .... LDI R31, (ptr_dport) >> 8 \ 0000002C 81A0 LD R26, Z \ 0000002E 81B1 LDD R27, Z+1 \ 00000030 912C LD R18, X \ 00000032 2321 AND R18, R17 \ 00000034 932C ST X, R18 Вариант 2 исправленный: работает Код volatile unsigned char *ptr_dport, *ptr_pin; unsigned char pin;
ptr_dport = &DDRD; ptr_pin = &PIND; pin = 1<<PD1;
8594 *ptr_dport |= pin; //0 на линии \ 00000002 9110.... LDS R17, pin \ 00000006 .... LDI R30, LOW(ptr_dport) \ 00000008 .... LDI R31, (ptr_dport) >> 8 \ 0000000A 8120 LD R18, Z \ 0000000C 8131 LDD R19, Z+1 \ 0000000E 01F9 MOVW R31:R30, R19:R18 \ 00000010 8120 LD R18, Z \ 00000012 2B21 OR R18, R17 \ 00000014 8320 ST Z, R18
8596 *ptr_dport &= ~pin; //1 на линии \ 00000024 9110.... LDS R17, pin \ 00000028 9510 COM R17 \ 0000002A .... LDI R26, LOW(ptr_dport) \ 0000002C .... LDI R27, (ptr_dport) >> 8 \ 0000002E 91ED LD R30, X+ \ 00000030 91FC LD R31, X \ 00000032 9711 SBIW R27:R26, 1 \ 00000034 8120 LD R18, Z \ 00000036 2321 AND R18, R17 \ 00000038 8320 ST Z, R18
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|