Микроконтролери и електроника
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);
}
}

И не работи пущината 8O След леко колебание и почивка си написах на асемблер програмката
и нещата се оправиха,но не ми е ясно къде греша в С-то.Някой да има някаква идея
след като е погледнал програмката ?

Автор:  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 ]
Заглавие: 

Мда така си е. Проблемът е само в маската.:oops: Още едно от добрите правила. Не използвай еднобуквени имена за променливите. Например вместо y->mask, вместо z->dword.

Автор:  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/