Programa para PIC 16F870
El siguiente código escrito en lenguaje C corresponde al programa que ejecuta el PIC 16F870 para controlar el DDS AD9854 y comunicarse con la PC.
El programa basicamente en un bucle sin fin que esta permanentemente leyendo el puerto serie en busca de comando enviados por la PC.
Los comandos son:
I -> Inicializa el DDS.
R -> Resetea el DDS.
P -> PTT
T -> Recibe 6 bytes desde la PC que definen la frecuencia de la señal a generar.
B -> Selección de banda (*)
(*) El port A del PIC es utilizado para la seleccion del filtro preselector pasabanda del QSD.
// Program to use a PIC 16F870 to control an AD9854 DDS.
// by LU3EBW - Oscar E. Ridolfi - 18/04/12
// Version 1.41
// See versioning information at the bottom of this document.
#include <16F870.h>
#include <stdlib.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000) // Proc speed 20Mhz.
#use rs232(baud=9600, xmit=PIN_B0, rcv=PIN_B1)
// Constants Definition.
// I/O port pins' function definition.
#define SoundPin PIN_B2 // Pin B2 used for beep generation.
#define IORST PIN_B3 // Pin B3 used to Reset the I/O state machine - Pin 17.
#define SDIO PIN_B4 // Pin B4 used as Serial Data I/O - Pin 19.
#define SClk PIN_B5 // Pin B5 used as Serial Clock - Pin 21.
#define PTTLine PIN_B6 // Pin B6 used to control the Tx-Rx lines.
// Low -> Rx | High -> Tx
// DDS Registers.
#define DdsWrCtrlReg 0x07 // Write Control Register - 4 Bytes
#define DdsUpdClkRate 0x05 // Update Clock Rate - 4 Bytes
#define DdsWrFTW1 0x02 // Write Freq. Tunning Word 1 - 6 Bytes
// DDS Initialization bytes.
#define CW4 0x10 // Control Word 4 - 0001 0000
#define CW3 0x0A // Control Word 3 - 0000 1010
#define CW2 0x01 // Control Word 2 - 0000 0001
#define CW1 0x40 // Control Word 1 - 0100 0000
#define UCR4 0x00 // Update Clock Rate Word 4
#define UCR3 0x00 // Update Clock Rate Word 3
#define UCR2 0xFF // Update Clock Rate Word 2
#define UCR1 0xFF // Update Clock Rate Word 1
#define LstBnd 0x00 // EEPROM address 0x00 holds the Last Band Selected.
// Global variables
int8 FTW1; // Freq Tuning Word 6
int8 FTW2; // Freq Tuning Word 5
int8 FTW3; // Freq Tuning Word 4
int8 FTW4; // Freq Tuning Word 3
int8 FTW5; // Freq Tuning Word 2
int8 FTW6; // Freq Tuning Word 1
int1 RxTxFlg; // False = Rx | True = Tx
int8 BndIdx; // Current Band selected index for Band array.
int8 Band[10] = { 6, 5, 4, 3, 2, 1, 0, 9, 8, 7 };
// Functions
//---------------------------------------------------------------------------------
void Beep(int8 t){ // t = beep times
int8 i,x=0;
for (x=t ; x > 0 ; x--){
for (i=0; i < 25 ; i++){
output_high (SoundPin);
delay_us(500);
output_low (SoundPin);
delay_us(500);
}
Delay_ms(100);
}
}
//---------------------------------------------------------------------------------
void AckToPC(){ // Send Ack (OK) to PC.
printf("OK\n");
}
//---------------------------------------------------------------------------------
void RstIO(){ // Reset I/O state machine
output_high (IORST);
output_low (IORST);
}
//---------------------------------------------------------------------------------
void PTT(){ // Toggle PTT line.
if (RxTxFlg) {
output_low (PTTLine);
RxTxFlg = False;
}
else {
output_high (PTTLine);
RxTxFlg = True;
}
}
//---------------------------------------------------------------------------------
void SendDataToDds(int8 Data){
int i;
/* printf("\n\r%lu %lX\n\r",Data,Data); */
// output_low (CS);
for(i=0 ; i<8 ; ++i){
output_bit(SDIO,shift_left(&Data,1,0));
delay_us(1);
output_high (SClk);
delay_us(1);
output_low (SClk);
}
}
//---------------------------------------------------------------------------------
void SendFwordToDds(){ // Send Freq Word to DDS.
RstIO();
SendDataToDds(DdsWrFTW1);
SendDataToDds(FTW6);
SendDataToDds(FTW5);
SendDataToDds(FTW4);
SendDataToDds(FTW3);
SendDataToDds(FTW2);
SendDataToDds(FTW1);
}
//---------------------------------------------------------------------------------
void InitializeDds(){ // Send Freq Word to DDS.
SendDataToDds(DdsWrCtrlReg);
SendDataToDds(CW4);
SendDataToDds(CW3);
SendDataToDds(CW2);
SendDataToDds(CW1);
RstIO();
SendDataToDds(DdsUpdClkRate);
SendDataToDds(UCR4);
SendDataToDds(UCR3);
SendDataToDds(UCR2);
SendDataToDds(UCR1);
}
//---------------------------------------------------------------------------------
void BndSel(Int8 BndByte){ // Band Select
output_a(BndByte); // Output to Rx Bandpass filters to select the appropriate filter.
Beep(1);
}
// Program
main(){
char cmd; //Cmd: Command received from PC
char DataFromPC[5];
output_low (IORST); // Initialize SPI pins.
output_low (SDIO);
output_low (SClk);
output_low (PTTLine);
RxTxFlg = False;
FTW6=0xCC; // Start-up frequency
FTW5=0xCC; // values = 0x400000000000 = 3,570khz
FTW4=0xD0;
FTW3=0x00;
FTW2=0x00;
FTW1=0x00;
RstIO();
InitializeDds();
SendFwordToDds(); // Send Frecuenct Word to DDS
Beep(2); // DDS and Rx Filters initialization completed.
do{
do{
cmd=getch();
}while(cmd != 'I' && cmd != 'R' && cmd != 'P' && cmd != 'T' && cmd != 'B');
if (cmd == 'I'){ // I --> Initialize DDS
InitializeDds();
AckToPC();
Beep(1);}
else if (cmd == 'R'){ // R --> Reset DDS
RstIO();
AckToPC();
Beep(1);}
else if (cmd == 'P'){ // P --> Toggle PTT Line.
PTT();
AckToPC();
Beep(1);}
else if (cmd == 'T'){ // T --> Six bytes to form the Frequency Word.
AckToPC();
gets(DataFromPC); //
FTW6=atoi(DataFromPC);
AckToPC();
gets(DataFromPC); //
FTW5=atoi(DataFromPC);
AckToPC();
gets(DataFromPC); //
FTW4=atoi(DataFromPC);
AckToPC();
gets(DataFromPC); //
FTW3=atoi(DataFromPC);
AckToPC();
gets(DataFromPC); //
FTW2=atoi(DataFromPC);
AckToPC();
gets(DataFromPC); //
FTW1=atoi(DataFromPC);
AckToPC();
SendFwordToDds();}
else if (cmd == 'B'){ // B --> Band Selection mode
AckToPC(); // Send Ack to PC
gets(DataFromPC); // Gets Band Selection Byte from PC
BndSel(atoi(DataFromPC)); // Call Band Select function
AckToPC();} // Send Ack to PC
}while(true);
}
// Versions
// v1.4 includes the band selection function and related code.
// v1.41 New Band Selection Method. The PC sends "B" and the band selection byte (BndByte) - 18/04/12
// 160m 0x06
// 80m 0x05
// 40m 0x04
// 30m 0x03
// 20m 0x02
// 17m 0x01
// 15m 0x00
// 12m 0x09
// 10m 0x08
// 6m 0x07