Pic18Fx52 Program - USART + PWM

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#16 Příspěvek od Andrea »

Vyrobíš si z hodnoty a čísla pinu masky (AND a OR) a těma vymaskuješ ten port.

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#17 Příspěvek od eXilim »

Uvažoval sem nad tím ale bohužel se mi to nepovedlo... Nelze nějak prostě doslova vybrat pin a pak do něj uložit hodnotu?

Uživatelský avatar
Atlan
Příspěvky: 4499
Registrován: 10 kvě 2004, 02:00
Bydliště: Košice

#18 Příspěvek od Atlan »

existuje nieco take

#define mono PORTEbits.RE2

a potom mozes mono=1; nastaví dany bit na log 1,,, mono=0; na 0
Inak je to nestandartne v ccku ale co uz...

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#19 Příspěvek od eXilim »

Atlan píše:existuje nieco take

#define mono PORTEbits.RE2

a potom mozes mono=1; nastaví dany bit na log 1,,, mono=0; na 0
Inak je to nestandartne v ccku ale co uz...

Kód: Vybrat vše

hodnota = get & 0x80;
pin = get & 0x7;

if(pin==0) RBpin0 = hodnota;
elseif(pin==1) RBpin1 = hodnota;
elseif(pin==10) RBpin2 = hodnota;
...
...
...
samozřejmě s tím definováním jak si psal... Není to taková trošku prasárna? :D Ale v tuhle chvíli je fakt, že mě nic jinýho nenapadá

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#20 Příspěvek od Andrea »

eXilim píše:elseif(pin==10) RBpin2 = hodnota;
Fakticky jsi někdy programoval v Cčku?

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#21 Příspěvek od eXilim »

Přímo C ne, C++, proč, co tam je špatně?

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#22 Příspěvek od Andrea »

No 10 je deset, tolik tam nikdy nebude, když to maskuješ 0x7. A hodnota je buď 0 nebo 0x80, co udělá když zapíšeš 0x80 do bitové proměnné?

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#23 Příspěvek od eXilim »

co máš na mysli tím zapíšeš?

Nemám psát 10 ale 0x2,0x3, ... ? Opravdu todle dělám poprve

a hodnotu odrotovat o 7doprava?

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#24 Příspěvek od Andrea »

eXilim píše:co máš na mysli tím zapíšeš?
RBpin0 = hodnota

A co jsi v tom C dělal? Dyť tohle jsou základy.

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#25 Příspěvek od eXilim »

kdyt píšu že to ještě odrotuju o 7 doprava :) takže mi tam zbyte 00000001 to už je snad přijatelný na zápis ne?

Jinak v C++ sem psal pár apliakcí pro win a dělám v tom web app (přes .net) ale tam sem takovýhle věci nikdy nepoužíval (o:

Kód: Vybrat vše

void setPin(unsigned char get) {
	unsigned char pin;
	unsigned char h;
	
	h = get & 0x80; //hodnota
	h = h >> 7;
	pin = get & 0x7;

	//nastavení pinu	
	if(pin == 0x0) 		RBPin0 = h;
	elseif(pin == 0x1) 	RBPin1 = h;
	elseif(pin == 0x2) 	RBPin2 = h;
	elseif(pin == 0x3) 	RBPin3 = h;
	elseif(pin == 0x4) 	RBPin4 = h;
	elseif(pin == 0x5) 	RBPin5 = h;
	elseif(pin == 0x6) 	RBPin6 = h;
	elseif(pin == 0x7) 	RBPin7 = h;
	
}

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#26 Příspěvek od piitr »

Kód: Vybrat vše

#include "18c252.h"
#include "uart.h"

unsigned long proc_type 0x8252;



void main() {
	unsigned char read;
	read = getRx();

	baudUSART (BAUD_IDLE_CLK_HIGH &
		BAUD_8_BIT_RATE &
		BAUD_WAKEUP_ON &
		BAUD_AUTO_ON);
//!!! Tohle by měl asi volat před tím getRx(). Po čtení je trochu pozdě ne?
//!!! Taky nechápu to &. Nemělo by se použít spíš OR než AND? Takhle vyjde vždycky nula, ne?

	if (read & 0x40) setPwm(read);
	else setPin(read);

	
}
unsigned char getRx() {
	unsigned char result;
	result = ReadUSART();
	return result;
}

void setPin(unsigned char get) {
	unsigned char pin;
	unsigned char hodnota;
	
	hodnota = get & 0x80;
	pin = get & 0xF;

	//nastavení pinu
//!!! Co tohle?
unsigned char mask; // to dát na začátek bloku
mask = 1 << pin;
if ( hodnota )
    portB |= mask;
else
    portB &= ~mask;
//!!! To portB má být port, ale já nevím, jak se ta proměnná jmenuje. To si najdi v dokumentaci k překladači.
//!!! Taky ten port asi budeš muset nejdřív nastavit, aby měl všechny piny výstupní, implicitně bývají vstupní.
}



Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#27 Příspěvek od eXilim »

Ano, ta inicializace má být předtím, neaktualizoval jsem tu kod, jsou tam & podle dokumentace knihoven pro překladač (http://ww1.microchip.com/downloads/en/D ... 51297f.pdf viz 2.10)

To maskování neovlivní bity které jsou už nastavené?
V tuhle chvíli to mám takto:

Kód: Vybrat vše

#include "p18c252.h"
#include "usart.h"
#include "pwm.h"


#pragma config OSC 	= HS
unsigned long proc_type 0x8252;

	

unsigned char getRx();
void setPin(unsigned char get);
void setPwm(unsigned char get);
void init();

void init() {
//inicializace uartu
	baudUSART (BAUD_IDLE_CLK_HIGH &
		BAUD_8_BIT_RATE &		//8 bitový přenos
		BAUD_WAKEUP_ON &		//Hlidání příchozí komunikace
		BAUD_AUTO_ON); 			//Automaticka rychlost
//inicializace portu
	TRISB = 0; 	//Všechny piny RB sou výstupní

//inicializace pwm
	SetOutputPWM1 (SINGLE_OUT, PWM_MODE_1);  //?
	OpenPWM1(0xFF); //?
	SetDCPWM1(0); //?
}

void main() {
	unsigned char read;
	init();

	read = getRx();
	if (read & 0x40) setPwm(read);
	else setPin(read);

	
}
unsigned char getRx() {
	unsigned char result;
	result = ReadUSART();
	return result;
}

void setPin(unsigned char get) {
	unsigned char pin;
	unsigned char h;
	unsigned char mask;
	
	h = get & 0x80; //hodnota
	h = h >> 7;
	pin = get & 0x7;

	mask = 1 << pin;
	if (h) PORTB |= mask;
	else PORTB &= ~mask; 
	
}
void setPwm(unsigned char get) {
	unsigned char frek;
	frek = get & 0x3F;  //00xxxxxx - Vyčteme frekvenci
	//změna frekvence PWM
	//?
	
}


Díky za pomoc

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#28 Příspěvek od piitr »

eXilim píše:Ano, ta inicializace má být předtím, neaktualizoval jsem tu kod, jsou tam & podle dokumentace knihoven pro překladač (http://ww1.microchip.com/downloads/en/D ... 51297f.pdf viz 2.10)
Aha, no jo, to je divný. Většinou to bývá přes OR, tohle jsem ještě neviděl.
eXilim píše: To maskování neovlivní bity které jsou už nastavené?
Jo a ne.
Když to uděláš na proměnnou v RAM, je to OK.
Prostuduj si bitové operace v nějaké učebnici C-čka.
Původní hodnota se z proměnné přečte, změní se v ní ten bit a pak se zase zpátky zapíše.
Takže se ty ostatní bity vlastně přečtou a pak se opět zapíšou.
U proměnné v RAM to nevadí, ale u portu to může někdy být problém, protože čtení čte (většinou) skutečné napětí na pinu.
Takže by se ti mohlo stát, že se ti ta hodnota ostatních bitů změní.
Třeba tehdy, když ten pin má otevřený kolektor, ty jsi zapisoval 1 a někdo jiný tam dával 0 - pak si zapamatuješ tu nulu.
Jde to ošetřit tím, že si tu hodnotu, kterou chceš zapisovat pamatuješ v nějaké proměnné, tam si ji upravuješ a po změně ji celou přepíšeš do portu. Pak ten port nikdy nečteš a je to OK.
eXilim píše:V tuhle chvíli to mám takto: ...
To by asi mohlo fungovat. Teda, ty inicializace jsem nekontroloval. To neznám.

Uživatelský avatar
eXilim
Příspěvky: 44
Registrován: 19 kvě 2010, 02:00

#29 Příspěvek od eXilim »

No já budu výstupy používat pouze na ledky, nebo ovládání tranzitoru ...


Návrh na to ošetření:

Kód: Vybrat vše

#include "p18c252.h"
#include "usart.h"
#include "pwm.h"


#pragma config OSC 	= HS
unsigned long proc_type 0x8252;
unsigned char pB = 0x0; //Nadefinuju proměnou pB kde bude uložená vždy poslední hodnota PORTB
	

unsigned char getRx();
void setPin(unsigned char get);
void setPwm(unsigned char get);
void init();

void init() {...
}



void setPin(unsigned char get) {
	unsigned char pin;
	unsigned char h;
	unsigned char mask;
	
	h = get & 0x80; //hodnota
	h = h >> 7;
	pin = get & 0x7;

	mask = 1 << pin;
	if (h) pB |= mask;
	else pB &= ~mask;
	PORTB = pB; 
}
Co myslíš?

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#30 Příspěvek od piitr »

Přesně tak jsem to myslel.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“