В чем ошибка

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

Недавно начал изучать ARM. сделал генератор синусоидального сигнала.. но что за сопли висят. не могу понять. кто знает, как от них можно избавиться?
СпойлерИзображение
текст проги:


#include "nxp/iolpc2104.h"

const unsigned int ab[]={ 0x7F, 0x82, 0x85, 0x88, 0x8B, 0x8F, 0x92, 0x95,
0x98, 0x9B, 0x9E, 0xA1, 0xA4, 0xA7, 0xAA, 0xAD,
0xB0, 0xB2, 0xB5, 0xB8, 0xBB, 0xBE, 0xC0, 0xC3,
0xC6, 0xC8, 0xCB, 0xCD, 0xD0, 0xD2, 0xD4, 0xD7,
0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE3, 0xE5, 0xE7,
0xE9, 0xEA, 0xEC, 0xEE, 0xEF, 0xF0, 0xF2, 0xF3,
0xF4, 0xF5, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB,
0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC,
0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, 0xF5,
0xF4, 0xF3, 0xF2, 0xF0, 0xEF, 0xEE, 0xEC, 0xEA,
0xE9, 0xE7, 0xE5, 0xE3, 0xE1, 0xDF, 0xDD, 0xDB,
0xD9, 0xD7, 0xD4, 0xD2, 0xD0, 0xCD, 0xCB, 0xC8,
0xC6, 0xC3, 0xC0, 0xBE, 0xBB, 0xB8, 0xB5, 0xB2,
0xB0, 0xAD, 0xAA, 0xA7, 0xA4, 0xA1, 0x9E, 0x9B,
0x98, 0x95, 0x92, 0x8F, 0x8B, 0x88, 0x85, 0x82,
0x7F, 0x7C, 0x79, 0x76, 0x73, 0x6F, 0x6C, 0x69,
0x66, 0x63, 0x60, 0x5D, 0x5A, 0x57, 0x54, 0x51,
0x4E, 0x4C, 0x49, 0x46, 0x43, 0x40, 0x3E, 0x3B,
0x38, 0x36, 0x33, 0x31, 0x2E, 0x2C, 0x2A, 0x27,
0x25, 0x23, 0x21, 0x1F, 0x1D, 0x1B, 0x19, 0x17,
0x15, 0x14, 0x12, 0x10, 0x0F, 0x0E, 0x0C, 0x0B,
0x0A, 0x09, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03,
0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x09,
0x0A, 0x0B, 0x0C, 0x0E, 0x0F, 0x10, 0x12, 0x14,
0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x23,
0x25, 0x27, 0x2A, 0x2C, 0x2E, 0x31, 0x33, 0x36,
0x38, 0x3B, 0x3E, 0x40, 0x43, 0x46, 0x49, 0x4C,
0x4E, 0x51, 0x54, 0x57, 0x5A, 0x5D, 0x60, 0x63,
0x66, 0x69, 0x6C, 0x6F, 0x73, 0x76, 0x79, 0x7C



};
void main(void)
{




unsigned i;

short int l,c;
unsigned long delay;


IODIR=0x000000FF;
while(1)
{

for(i=0;i<256;i++)
{


IOCLR = ~ab;
IOSET = ab;
for(delay = 0; delay < 0x100; delay++)
{
;
}
}
}
Вложения
arm7_dac2.rar
(731.95 КБ) 205 скачиваний
main.c
(2.3 КБ) 414 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20101
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Похоже что когда переключается старший разряд, глюкает.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Друг Кота
Аватара пользователя
Сообщения: 26834
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Сообщение Муркиз »

от 0 до 256 ?
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

от 0 до 255 (<256)
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Код: Выделить всё

IOCLR = ~ab[i];
IOSET = ab[i];

Это что? Виртуальная симуляция на то и виртуальная, что видит все изменения сигнала. Когда выполняется первая строка, на выходе МК получается мусор (при чём по значению меньше чем было), который и даёт сопли (очень малой длительности), и только после выполнения второй строки на выходе правильное значение.
Выставляй сразу нужное значение в порт, без этих "передергиваний" битов.

Может выглядеть как

Код: Выделить всё

GPIO0->ODR = ab[i];
только структурно правильно для данного МК.

Либо вариант: поставить фильтр НЧ на выходе.

P.S. А, кажется понял. Тут нет возможности непосредственно установки состояния выхода. Тогда можно или фильтр поставить, или... ну буферный регистр поставить с защёлкой, но проще просто в ОУ добавить конденсатор, чтобы сделать из него фильтр.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

GPIO Pin Value Register (IOPIN - 0xE0028000)
This register provides the value of the GPIO pins. This value reflects any outside world influence on the pins.
Note: for test purposes, writing to this register stores the value in the output register, bypassing the need to use both the IOSET and IOCLR registers. This feature is of little or no use in an application because it is not possible to write to individual bytes in this register.
ЗЫ. Наверное лучше взять что-то посвежее.
Реклама
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

старье?
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Да, попробуй использовать IOPIN или добавь просто конденсатор:
Изображение

Его ёмкость бери равной
C = 1/(4*pi*fmax*R1)
fmax - максимальная частота генерируемого сигнала.

Такие импульсы должны с лёгкостью фильтроваться. Фильтр в любом случае хорошо поставить.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

старье?
Есть смысл заморачиваться если достались бесплатно либо уже закуплена партия под серию.
А так, те же кортексы уделают их что по цене(по крайней мере в нашем ларьке), что по периферии.
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

значит на ARM7 нельзя сделать простой генератор?
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

ну вы же сделали
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

но остались сопли
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Но ведь уже 5 раз разобрали в чём дело и как исправить. Этого недостаточно? )
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

IOPIN нельзя использовать.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

В описании написано (цитата от uk8amk), что можно в него писать.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

http://caxapa.ru/22498.html 10 лет назад тоже такой же вопрос поднимали...и нифига... нельзя в IOPIN писать
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула

Сообщение IfoR »

Код: Выделить всё

*((int*)(0xE0028000)) = ab[i];
Не даёт никаких результатов?
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Никакого противоречия с цитатой из UM.

Давноб уже попробовали, причём желательно не в протеусе.
Нашел транзистор. Понюхал.
Сообщения: 183
Зарегистрирован: Сб фев 09, 2013 23:00:23

Сообщение alexf58 »

Dj_Crush писал(а):http://caxapa.ru/22498.html 10 лет назад тоже такой же вопрос поднимали...и нифига... нельзя в IOPIN писать
Боюсь вы не поняли о чем речь. Если надо выдавать в порт параллельный код, то писать в IOPIN можно и нужно. В вашем простом случае больше не о чем и задумываться. Сложности начинаются если, скажем, надо писать в 8 бит, а другие несколько бит этого же порта должны остаться как были. Тогда надо прочитать старое значение, поменять 8 нужных бит, и записать снова. А если вдруг случится прерывание между чтением и записью, может быть сбой. Тогда надо операцию чтения-модификации-записи делать "атомарной", т.е. запретить прерывания на время этой операции.

Псевдо код безопасной записи в младшие 8 бит порта:

disable_int();
old_val = IOPIN;
IOPIN = (old_val & 0xff00) | ab;
enable_int();

Для того, чтобы не связываться с такими усложнениями и сделали отдельные регистры сброса/установки. Чтобы можно было установить один или несколько бит без того, чтобы сначала читать остальные. Кстати в LPC2104/01, LPC2105/01, and LPC2106/01 еще предусмотрен регистр МАСКИ. Он позволяет писать не стесняясь в отдельные биты, не трогая другие.

http://www.nxp.com/documents/user_manual/UM10275.pdf в помощь.
Родился
Сообщения: 16
Зарегистрирован: Пн июн 09, 2014 05:59:47

Сообщение Dj_Crush »

IAR не знает что такое IOPIN,и не работает disable_int()... как можно исправить эту проблему?
Последний раз редактировалось Dj_Crush Ср янв 21, 2015 13:47:15, всего редактировалось 1 раз.
Ответить

Вернуться в «ARM»