| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Преобразуване на данни http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=4977 |
Страница 1 от 1 |
| Автор: | Ки4о [ Пет Окт 19, 2007 10:20 pm ] |
| Заглавие: | Преобразуване на данни |
Проблема е следния: 32 битово число трябва да се предаде по сериен канал.Написах следната програма на PICC на HiTech за PIC16F874 ама нещо неще да става: #ifndef _16F874 #define _16F874 #endif #include <pic.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include "delay.h" __CONFIG( HS & PWRTEN & BORDIS & WDTDIS & LVPDIS & DEBUGDIS & UNPROTECT); static bit EN @ ((unsigned)&PORTE*8+0); static bit DATA @ ((unsigned)&PORTE*8+1); static bit CLOCK @ ((unsigned)&PORTE*8+2); unsigned long x,y,z,data1; void init_2 (void){ GIE=0; // enable A2D converter ADIE = 0; // not interrupt driven ADCON0= 0b00000001; //DISABLE ADC ADCON1= 0b00000110; //ALL DIGITAL PORTA = 0; TRISA = 0b0000000; // ALL OUTPUT PORTA = 0; PORTB = 0; TRISB = 0b00000000; PORTB = 0; PORTC = 0; TRISC = 0b00000000; PORTC = 0; PORTD = 0; TRISD = 0b00000000; PORTD = 0; PORTE = 0; TRISE = 0b00000000; PORTE = 0; } SendByte(unsigned long z ) { int i; i=0; EN=0; DATA=0; CLOCK=0; for(i=0;i<32;i++) { y=0x800000; //маска x=((z)&(y)); if(x>0) { DATA=1; } else { DATA=0; } z=(z<<1); CLOCK=1; asm("nop"); CLOCK=0; asm("nop"); DATA=0; } EN=1; } void main() { init_2(); for(;;) { data1=0x3F3F3F3F; SendByte(data1); DelayMs(500); DelayMs(500); } } И не работи пущината и нещата се оправиха,но не ми е ясно къде греша в С-то.Някой да има някаква идея след като е погледнал програмката ? |
|
| Автор: | woody [ Съб Окт 20, 2007 2:23 am ] |
| Заглавие: | |
За начало маската с която въртиш е 2^23 вместо 2^31 (0x80000 --> 0x80000000). |
|
| Автор: | Zdrav [ Съб Окт 20, 2007 8:35 am ] |
| Заглавие: | |
Тя маската е по-малкия проблем. Функцията SendByte е логично да изпраща само един байт. Добрите принципи изискват това което прави функцията да отговаря на името и. В този случай, трябва да подаваш като аргумент байт. И за да изпратиш 32 битова дума извикваш SendByte 4 пъти за всеки байт от думата. Реда в който ще подаваш байтовете зависи от това какво ти е договорено със отсрещната страна - Little или Big Endian. Всъщност и сега функцията ти изпраща така. Започваш от маска 0x00800000 и шифтваш 32 пъти на ляво?!? Така както си го написал предаваш най-старшите 9 бита от z и след това 23 бита нули. В някои случаи е по-удобно записването (1<<23) вместо 0x00800000. Това е по С кода, не мога да кажа нищо по частта за конфигуриране щото не съм работил с PIC-ове. |
|
| Автор: | Ки4о [ Съб Окт 20, 2007 9:12 am ] |
| Заглавие: | |
Маската я промених - 0х80000000 -> 1000 0000 0000 0000 0000 0000 0000 0000. Като се направи едно И със 0101 1100 0000 0000 0100 1100 0110 0110,резултата 0 и в зависимост от това дали е 0/1 си управлявам пина.Това измислих за тестване на бит в long.Незнам как се тества по друг начин.Маската си е постоянна. Шифтвам само z 32 пъти наляво. |
|
| Автор: | VSU [ Съб Окт 20, 2007 12:38 pm ] |
| Заглавие: | |
Я пробвай така SendByte(unsigned long z ) { char i; EN=0; DATA=0; CLOCK=0; for(i=0;i<32;i++) { if(z & 0x80000000) DATA=1; else DATA=0; z <<= 1; CLOCK=1; asm("nop"); CLOCK=0; asm("nop"); } EN=1; } |
|
| Автор: | Zdrav [ Съб Окт 20, 2007 12:46 pm ] |
| Заглавие: | |
Мда така си е. Проблемът е само в маската. |
|
| Автор: | bateAz [ Съб Окт 20, 2007 1:12 pm ] |
| Заглавие: | |
Send4B(unsigned long inp) { char *p; char i; p = (char*)(&inp); for (i=0; i<4; i++) { SendByte(*p); p++; } } Това ? |
|
| Автор: | Реконструктор [ Нед Окт 21, 2007 12:53 pm ] |
| Заглавие: | |
Не забравяйте Endian-a |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|