Reystlin
-
Постов
128 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные Reystlin
-
-
unsigned long AD7799_GetRegisterValue(unsigned char CS,unsigned char regAddress, unsigned char size) { unsigned char data[4] = {0x00, 0x00, 0x00, 0x00}; unsigned long receivedData = 0x00; data[0] = AD7799_COMM_READ | AD7799_COMM_ADDR(regAddress); AD7799_CS_LOW(CS); AD7799_SpiTransferByte(data[0]); for(char i=0;i<size;i++) data[i]=AD7799_SpiTransferByte(data[i]); AD7799_CS_HIGH(CS); if(size == 1) { receivedData += (data[0] << 0); } if(size == 2) { receivedData += (data[0] << 8); receivedData += (data[1] << 0); } if(size == 3) { receivedData += (data[0] << 16); receivedData += (data[1] << 8); receivedData += (data[2] << 0); } return receivedData; }
вот здесь 3 итерации цикла проходит и потом все что считалось склеивается со сдвигом
-
ацп у меня работает в непрерывном режиме измерений. после считывания данных измерение должно запускаться автоматически. Reg_ID считывается как 0х49
#define AD7799_CS_LOW(selected_chip) AD7799_CS_PORT->ODR &=~(selected_chip); #define AD7799_CS_HIGH(selected_chip) AD7799_CS_PORT->ODR |=(selected_chip); AD7799_CS_LOW(AD7799_CHIP3); SPI1->DR = 0x60; while(!(SPI1->SR & SPI_SR_RXNE)); weigt[3] = SPI1->DR; AD7799_CS_HIGH(AD7799_CHIP3); AD7799_CS_LOW(AD7799_CHIP3); SPI1->DR = 0x60; while(!(SPI1->SR & SPI_SR_RXNE)); weigt[3] = SPI1->DR; AD7799_CS_HIGH(AD7799_CHIP3);
-
1 hour ago, k155la3 said:
Может оно ?
Ну, еще уровень функций интерфейса SPI надо проверять.
так я же ничего в дата регистр не пишу.
unsigned char AD7799_SPI_Init( void ) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//Включаем тактирование SPI1 //Настройка внутреннего SPI1 SPI_InitTypeDef spi; SPI_StructInit(&spi); spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//Направление передачи spi.SPI_Mode = SPI_Mode_Master; //Режим передачи spi.SPI_DataSize = SPI_DataSize_8b; //Размер пакета spi.SPI_CPOL = SPI_CPOL_High; //idle тактового сигнала spi.SPI_CPHA = SPI_CPHA_2Edge; //рабочий фронт тактового сигнала spi.SPI_NSS = SPI_NSS_Soft; //режим работы пина NSS spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;//Предделитель spi.SPI_FirstBit = SPI_FirstBit_MSB; //Первый бит - младший spi.SPI_CRCPolynomial = 7; //Контрольная сумма SPI_Init(SPI1, &spi); SPI_Cmd(SPI1, ENABLE); //Насройка выводов под SPI1 GPIO_InitTypeDef port; GPIO_StructInit(&port); port.GPIO_Mode = GPIO_Mode_AF_PP; port.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; port.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &port); //Насройка выводов под ~CS GPIO_StructInit(&port); port.GPIO_Mode = GPIO_Mode_Out_PP; port.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6; port.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(AD7799_CS_PORT, &port); AD7799_CS_PORT->ODR |=((1<<4)|(1<<5)|(1<<6)); return(1); } unsigned char AD7799_SpiTransferByte(unsigned char data) { unsigned char temp; SPI1->DR = data; while(!(SPI1->SR & SPI_SR_RXNE)); temp = SPI1->DR; return temp; }
-
Tektronix MSO2002B показывает, что с шиной данных и CS разных чипов все в порядке
-
Опубликовано · Изменено пользователем Reystlin · Пожаловаться
3 minutes ago, k155la3 said:У Вас работа с одним чипом АЦП и одним его каналом получается корректно ?
Не знаю, по-моему Вам надо пересмотреть построение (логику) функций интерфейса. Если это не Ваш код изначально, тем более.
Так как наличие и время устновки CS я не вижу.
Где-то в подобном стиле (хотя, "дело вкуса")
int AD77xx_IsReady(void) { if( AD77xx_GetStatus() & 0x80 ) return(0); else return(1); }; // не помню, возможно инверсно
тогда считывание
SPI_CS_ACTIVE_ADC_00 (макро, устанавливает нолик на нужный пин порта) // ---------------- if( AD77xx_IsReady() ) { AD77xx_SetChannel( 0 ); if( AD77xx_IsReady() ) AD77xx_Go(); else .... error } else . . . . wait or error ..... // ---------------- SPI_CS_PASSIVE_ADC_00
Я взял пример от аналогдевайс, переписал там ф-и раоты в SPI и дописал нехватающих функций
вот код где CS дергается и происходит отправка и прием данных
unsigned long AD7799_GetRegisterValue(unsigned char CS,unsigned char regAddress, unsigned char size) { unsigned char data[4] = {0x00, 0x00, 0x00, 0x00}; unsigned long receivedData = 0x00; data[0] = AD7799_COMM_READ | AD7799_COMM_ADDR(regAddress); AD7799_CS_LOW(CS); AD7799_SpiTransferByte(data[0]); for(char i=0;i<size;i++) data[i]=AD7799_SpiTransferByte(data[i]); AD7799_CS_HIGH(CS); if(size == 1) { receivedData += (data[0] << 0); } if(size == 2) { receivedData += (data[0] << 8); receivedData += (data[1] << 0); } if(size == 3) { receivedData += (data[0] << 16); receivedData += (data[1] << 8); receivedData += (data[2] << 0); } return receivedData; } void AD7799_SetRegisterValue(unsigned char CS,unsigned char regAddress, unsigned long regValue, unsigned char size) { unsigned char data[4] = { 0x00, 0x00, 0x00, 0x00}; data[0] = AD7799_COMM_WRITE | AD7799_COMM_ADDR(regAddress); if(size == 1) { data[1] = (unsigned char)regValue; } if(size == 2) { data[2] = (unsigned char)((regValue & 0x0000FF) >> 0); data[1] = (unsigned char)((regValue & 0x00FF00) >> 8); } if(size == 3) { data[3] = (unsigned char)((regValue & 0x0000FF) >> 0); data[2] = (unsigned char)((regValue & 0x00FF00) >> 8); data[1] = (unsigned char)((regValue & 0xFF0000) >> 16); } AD7799_CS_LOW(CS); for(char i=0;i<=(size);i++) AD7799_SpiTransferByte(data[i]); AD7799_CS_HIGH(CS); }
На данный момент задействован 1 ацп и 1 его канал
-
7 minutes ago, k155la3 said:
обратите внимание на Table 5. Output RMS Noise (µV) vs. Gain and Output Update Rate for the AD7798 Using a 2.5 V Reference
и на табл. Table 14. Update Rates Available. Чем выше частота запуска АЦП, тем меньше у Вас получится достоверная разрядность.
При переключении канала следует учитывать время на "установление" режима входа АЦП (при наличии внешних RC фильтров, усилителей, конденсаторов).
Это аналогично настройке времени отработки УВХ для АЦП посл. приближения.
После старта АЦП готовность данных определяйте по биту в регистре статуса. То что вы показали на видео, похоже на несвоевременное считывание.
считывание сейчас сделано вот таким кодом
unsigned char rdy = 0; unsigned long reg_stat= AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_STAT,1); rdy = (reg_stat & 0x80); if((rdy==0x80)&&((reg_stat& 0x07)==0x00)) rdy=1; if((rdy==0x80)&&((reg_stat& 0x07)==0x01)) rdy=2; if((rdy==0x80)&&((reg_stat& 0x07)==0x02)) rdy=3; weigt[0]=reg_stat; weigt[1]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_MODE,2); weigt[2]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_CONF,2); weigt[3]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_OFFSET,3); weigt[4]=AD7799_GetRegisterValue( AD7799_CHIP3,AD7799_REG_FULLSALE,3); switch(rdy) { case 1: weigt[5] = filter(ADCFilter(4,AD7799_GetRegisterValue(AD7799_CHIP3, AD7799_REG_DATA,3))); break; case 2: //weigt[5]=AD7799_GetRegisterValue(AD7799_CHIP3, AD7799_REG_DATA,3); break; } }
т.е. происходит только по наличию бита готовности в регистре статуса
-
13 minutes ago, Ruslan1 said:
Это несколько интересных эффектов:
1. перезаряд всех имеющихся в схеме емкостей на входе АЦП (и внешних реальных-паразитных и внутренней) от неизвестного уровня предыдущего входа к новому измеряемому уровню током нового подключенного измеряемого входа, с учетом входного сопротивления АЦП и других токов утечки.
2. перегрузка фильтр АЦП новыми данными. Процесс и технология обычно описаны в даташите АЦП. Но следует понимать, что сеачала должно произойти (1) и тольео потом начаться (2).
У меня был случай, когда, паразитные емкости электронных коммутаторов мешали. Вводил даже специальный вход, перезаряжающий все емкости измерителя до среднего уровня, от которого уже можно было посчитать максимальное время перезаряда до измеряемого уровня. То есть In1-Ref-In2-Пауза-Измерение_In2.
Это все считается (ну или хоть симулируется в симуляторе как набор цепочек R-C), подбирать тут опасно- будет на одном входе -Vmax, а на другом входе +Vmax, и окажется что емкости недоперезарядились.
тензодатчик же низкоомный прибор. ток перезарядки этих емкостей будет достаточно большим
-
Опубликовано · Изменено пользователем Reystlin · Пожаловаться
11 minutes ago, alexunder said:Встречал такое у АЦП с мултиплексором на входе, вроде у AD7949. Канал с низким напряжением на входе хорошо чувствовал своего соседа (опрошенного перед ним), у которого на входе был потенциал заметно выше (в режиме по умолчанию эта ИМС перебирала каналы последовательно от 0 до N). Проблема решилась отключением режима последовательного перебора канала и двух- трехкратным чтением каждого канала.
Пробовал делать переключение каналов на каждое 10ое измерение, все-равно каналы друг в друга проникают. после переключения один канал плавно подбирается к уровню второго
было решено отказаться от использования вторых каналов.
-
вывел все регистры на экран. считываю их в цикле измерений.
1 - STATUS
2 - MODE
3 - CONFIGURATION
4 - OFFSET
5 - FULLSALE
6- значение ацп.
по видео видны странности:
1. в моменты пауз в регистре статуса биты ready и error = 0
положительное усилие на датчик не влияет на эту ситуацию
но отрицательное усилие поднимает бит error сразу при его появлении(что в принципе нормально, на входе ацп отрицательное значение становится).
2. очень большая задержка между повышением показаний на выходе ацп и моментом приложения положительного усилия.
так-же после снятия положительного усилия с датчика с очень большой задержкой он возвращается в нулевое положение по показаниям.
куда копать? всю голову сломал, не могу понять природу происходящей магии
-
Опубликовано · Изменено пользователем Reystlin · Пожаловаться
Доброго времени суток ув. форумчане
Столкнулся я тут с задачей на AD7799, имеется 3 таких ацп на общей шине с раздельными CS ессно. К двум каналам каждого АЦП подключены свои мостовые тензодатчики.
Устройство занимается дозированием, посему требуется достаточно быстрый опрос значений с ацп с приемлимой точностью.
Столкнулся вот с какими проблемами:
1. Не совсем понятно как себя ведет внутренний фильтр.
На видео показана проблема.
5 число сверху - вход к которому подключен датчик.
результаты измерения ацп иногда замирают, причем на разное время.
так-же время замирания зависит от частоты фильтра. чем выше частота фильтра тем короче эти задержки
режим работы ацп - непрерывный. данные считываю по флагу в регистре статуса.
2. Если часто переключать каналы то возникает проникание сигнала одного канала в другой. я подозреваю, что это связано с наличием фильтра после преобразователя а каналы там муксом на входе преобразователя выбираются... есть ли лайфхаки обойти сею проблему?
код инициализации:
void AD7799_Config(unsigned char chip) { AD7799_Init(chip); AD7799_SetUnipolar(chip,1); AD7799_SetGain(chip,AD7799_GAIN_1); AD7799_SetFilterMode(chip,AD7799_Filter_16_7_50hz); AD7799_SetChannel(chip,AD7799_CH_AIN2P_AIN2M); AD7799_SetMode(chip,AD7799_MODE_CAL_INT_ZERO); while(AD7799_Ready(chip)); AD7799_SetMode(chip,AD7799_MODE_CAL_INT_FULL); while(AD7799_Ready(chip)); AD7799_SetChannel(chip,AD7799_CH_AIN1P_AIN1M); AD7799_SetMode(chip,AD7799_MODE_CAL_INT_ZERO); while(AD7799_Ready(chip)); AD7799_SetMode(chip,AD7799_MODE_CAL_INT_FULL); while(AD7799_Ready(chip)); AD7799_SetFilterMode(chip,AD7799_Filter_10); AD7799_SetMode(chip,AD7799_MODE_CONT); }
код опроса регистра статуса
unsigned char AD7799_Ready(unsigned char CS) { unsigned char rdy = 0; unsigned long reg_stat= AD7799_GetRegisterValue( CS,AD7799_REG_STAT,1); rdy = (reg_stat & 0x80); if((rdy==0x80)&&((reg_stat& 0x07)==0x00)) rdy=1; if((rdy==0x80)&&((reg_stat& 0x07)==0x01)) rdy=2; if((rdy==0x80)&&((reg_stat& 0x07)==0x02)) rdy=3; return(rdy); }
код опроса ацп
switch(AD7799_Ready(AD7799_CHIP2)) { case 1: weigt[2] = AD7799_GetRegisterValue(AD7799_CHIP2, AD7799_REG_DATA,3); AD7799_SetChannel(AD7799_CHIP2,AD7799_CH_AIN2P_AIN2M); break; case 2: weigt[3] = AD7799_GetRegisterValue(AD7799_CHIP2, AD7799_REG_DATA,3); AD7799_SetChannel(AD7799_CHIP2,AD7799_CH_AIN1P_AIN1M); break; }
-
все никак не могу нормально сделать экспорт из Solidworks PCB в Solidworks....
сейчас вот с какой проблемой столкнулся
есть плата, на ней стоят детали нарисованные вручную в солиде и вставленные в библиотеку.
нажимаю кнопку Push в Solidworks PCB Collaboration, все проходит без ошибок, в папке проекта создается папка в которой повляются парасолидовские файлы компонентов, эти файлы открываются солидом отдельно без проблем.
когда в солиде нажимаю Pull Board from PCB Services, начинается процесс загрузки платы, и вылетает ошибка "Failed to import: D:\Projects\Downloaded Models\POSISTOR16P_Rp.x_t, error: 0"
при этом в рабочей папке так-же появляются файлы парасолидовских моделей но вот они уже солидом отдельно не открываются...
открыл одинаковые файлы из разных папок и заметил, что в папке, которую создает PCB там в координатах для дробной части используется точка а вот в файлах которые создает солид уже точки заменены на запятые....
-
СТЕП начал открываться после того, как положение начальной точки на плате поменял
-
Парасолидовские файлы после сохранения в альтиуме у меня в солиде не открываются..
-
а что за другие варианты?
-
где взять этот плагин? как ставить?
-
каким образом можно электрически соединить Pad-ы с разными десигнаторами внутри одного компонента?
-
Про Solidworks PCB вкурсе, но там некоторые вещи криво реализованы....
-
Опубликовано · Изменено пользователем Reystlin · Пожаловаться
как его на ломанный альтиум поставить?
и что за решение от Dassault ?
-
Доброго времени суток ув. форумчане
кто какой метод использует, чтобы подружить эти две замечательные софтины?
-
Доброго времени суток ув. форумчане
юазю для составления схем и разводки ПП пакет Solidworks PCB, по сути тот-же Альтиум, но упрощенный.
понадобилось нарисовать футпринт для компонента, у которого два вывода внутри корпуса соединены
Вычитал, что в Альтиуме для этого есть параметр у Pad-a Jubmer ID, в Солиде он тоже есть, установил там одинаковые номера отличные от 0 и присовил Pad-ам разные Designator-ы, но Солид не хочет их электрически связывать...
-
так ведь полуавтомат это источник напряжения с ограничением по току, это дуговой и тиг аппараты являются источниками тока с ограничением по напряжению
по сути мы должны сбрасывать напряжение источника при резком увеличении тока но с регулируемой динамикой
-
Спасибо за ответы, кажется необходимо конкретизировать суть моего вопроса
разрабатываю сварочный инверторный полуавтомат с управлением на мк.
в трансформаторных полуавтоматах на выходе ставился дроссель, который при касании проволоки и заготовки "смягчал" ситуацию но для различных режимов необхдима различная индуктивность этого дросселя
в инверторе я думаю производить замеры тока, по которым вносить корректировку в задатчик так, чтобы источник вел себя как-будто бы у него на выходе стоит дроссель
-
Доброго времени суток ув. форумчане
Пытаюсь создать проект в IAR под STM32F401C-Discovery опираясь на видеоуроки с канала https://www.youtube.com/channel/UCZqlkhxfy2hA045jEBp9vwA
все было замечательно до тех пор, пока не раскомменитровал строку #define STM32F401xx в файле stm32f4xx.h
после чего начинают сыпаться ошибки
что делаю не так?
прикладываю архив с проектом
нашел проблему...
в свойствах проекта был один тип МК указан а в h файле другой тип раскомментирован
-
Доброго времени суток, ув. форумчане
Возникла у меня потребность сделать на микроконтроллере аналог дросселя с регулируемой индуктивностью.
т.е. подаем на АЦП сигнал, а с ЦАПа получаем уже сигнал такой-же как-будто бы мы его пропустили через дроссель а не микроконтроллер
аппаратно думаю ставить STM32F407
каким образом лучше всего реализовать такую задачу?
мне на ум пока приходит только вот такое решение задачи
X1(t1), X2(t2) - измерения АЦП
x = X2 -L*((x2-x1)/(t2-t1))
AD7799
в В помощь начинающему
Опубликовано · Изменено пользователем Reystlin · Пожаловаться
этот кусок кода был позаимствован из библиотеки от АД
а почему нет? у нас 8 бит загружается в АЛУ, АЛУ сдвигает их влево и возвращает полученный результат регистры у STM32 32х разрядные...
з.ы. код из библиотеки от АД
взято отсюда https://wiki.analog.com/resources/tools-software/uc-drivers/renesas/ad7799