0% found this document useful (0 votes)
120 views36 pages

AVR and LC72131

Uploaded by

Gary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
120 views36 pages

AVR and LC72131

Uploaded by

Gary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

The AVR Freaks Forum will be undergoing site maintenance from Friday Jun 14th 2PM MST through

Sunday
Jun 16th 5PM, during which time the login service will be impacted. Please keep your usage in VIEW ONLY
mode until the site maintenance is completed. Thanks for your understanding!

(/s/) About Community (/s/about-community)

Forums (/s/forums)
Welcome to the AVR Freaks Community
Log In / Register (https://www.avrfreaks.net/services/auth/sso/Community_portal_oAuth?
The premier community for all things 8 and 32-bit AVR microcontrollers.
startURL=%2Fs%2Ftopic%2Fa5C3l000000UcRUEA0%2Ft161564)

Search for a topic

AVR Freaks / Forums (/s/forums) / AVR Microcontrollers / megaAVR and tinyAVR /


AVR and LC72131

AVR and LC72131


Go To Last Comment

Posted By: rpz3598


Posted: 11 Jun 2021 - 07:06 PM
Last Comment Date: 31 Dec 2023 - 05:14 PM
Views: 2723
Comments: 19 Ranking:

AUTHOR

TOPIC

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Attachments: 1_20.jpg (/sfc/servlet.shepherd/document/download/0693l00000VHTUfAAP), lc72131.pdf


(/sfc/servlet.shepherd/document/download/0693l00000VHTpMAAX), V211_0.zip (/sfc/servlet.shepherd/doc
ument/download/0693l00000VHTOrAAP)

19 Comments

Author Posted: 11 Jun 2021 - 07:13 PM Last Updated: 11 Jul 2021 - 08:20 AM #1 0 0
rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Some examples from the Internet with hard SPI using:


...
#define F_UPDATE_LC72131 0x01

#define LC72131_IN1_CMD 0x28


#define LC72131_IN2_CMD 0x29

// IN1 (3rd byte)


#define LC72131_SNS 0x01 // AMIN prescaler 1=on (2 to 40 MHz), 0=off (0.5 t
#define LC72131_DVS 0x02 // Input select: 0=AMIN, 1=FMIN
#define LC72131_CTE 0x04 // IF counter: 1=start, 0=
#define LC72131_XS 0x08 // XTAL: 1=7.2MHz, 0=4.5MH

#define LC72131_REF_100K 0x00 // 100 kHz reference


#define LC72131_REF_50K 0x10 // 50 kHz reference
#define LC72131_REF_25K 0x20 // 25 kHz reference
#define LC72131_REF_12K5 0x40 // 12.5 kHz reference
#define LC72131_REF_6K25 0x50 // 6.25 kHz reference
#define LC72131_REF_3K125 0x60 // 3.125 kHz reference
#define LC72131_REF_10K 0x80 // 10 kHz reference
#define LC72131_REF_9K 0x90 // 9 kHz reference
#define LC72131_REF_5K 0xA0 // 5 kHz reference
#define LC72131_REF_1K 0xB0 // 1 kHz reference
#define LC72131_REF_3K 0xC0 // 3 kHz reference
#define LC72131_REF_15K 0xD0 // 15 kHz reference
#define LC72131_STOP 0xE0 // PLL inhibit + XTAL stop
#define LC72131_INHIBIT 0xF0 // PLL inhibit

// IN2 (1st byte)


#define LC72131_IOC1 0x01 // IO1 pin mode: 1=out, 0=in
#define LC72131_IOC2 0x02 // IO2 pin mode: 1=out, 0=in
#define LC72131_IO1 0x04 // IO1 pin state: 1=low, 0
#define LC72131_IO2 0x08 // IO2 pin state: 1=low, 0
#define LC72131_BO1 0x10 // BO1 pin state: 1=low, 0
#define LC72131_BO2 0x20 // BO2 pin state: 1=low, 0
#define LC72131_BO3 0x40 // BO3 pin state: 1=low, 0
#define LC72131_BO4 0x80 // BO4 pin state: 1=low, 0

// IN2 (2nd byte)


#define LC72131_DOC0 0x02 // DO pin control
#define LC72131_DOC1 0x04 // DO pin control
#define LC72131_DOC2 0x08 // DO pin control
#define LC72131_UL0 0x10 // unlock detection data
#define LC72131_UL1 0x20 // unlock detection data
#define LC72131_DZ0 0x40 // dead zone control
#define LC72131_DZ1 0x80 // dead zone control

// IN2 (3rd byte)


#define LC72131_GT0 0x01 // IF counter measurment t
#define LC72131_GT1 0x02 // IF counter measurment t
#define LC72131_TBC 0x04 // time base output
#define LC72131_DLC 0x08 // force charge pump outpu
#define LC72131_IFS 0x10 // IF counter input sensit

#define LC72131_BAND_UNMUTE LC72131_BO2


#define LC72131_BAND_NFM LC72131_BO3
#define LC72131_BAND_AM LC72131_BO4

//------------------------------------------------------------------------------
static void lc72131_cmd(uint8_t cmd, uint8_t data1, uint8_t data2, uint8_t data3)
{
// send address
spi_send(cmd);
// wait tEL (750 ns)
_delay_us(0.75);
// set CE
LC72131_PORT |= LC72131_CE;
// wait tES (750 ns)
_delay_us(0.75);
// send data
spi_send(data1);
spi_send(data2);
spi_send(data3);
// wait tEH (750 ns)
_delay_us(0.75);
// clear CE
LC72131_PORT &= ~LC72131_CE;
}

//------------------------------------------------------------------------------

void lc72131_setup()
{
static prog_uint8_t ref_data[RX_FREQ_STEP_COUNT] = {
LC72131_REF_1K,
LC72131_REF_3K125,
LC72131_REF_5K,
LC72131_REF_6K25,
LC72131_REF_12K5,
LC72131_REF_25K,
};

static prog_uint8_t band_data[RX_MOD_COUNT] = {


LC72131_IOC1 | LC72131_IOC2 | LC72131_BAND_AM, // AM
LC72131_IOC1 | LC72131_IOC2, // FM
LC72131_IOC1 | LC72131_IOC2 | LC72131_BAND_NFM, // NFM
};

uint8_t data;
uint16_t divisor, step;

// set SPI normal bit order


SPCR |= 1<<DORD;

// calculate divisor
step = pgm_read_word(rx_freq_step_value + rx_freq_step);
divisor = (RX_IF_1 - RX_IF_2 - (rx_freq % 50000)) / step;

//divisor = ((uint32_t)divisor * 1000) >> 10; // 7.3728 xtal fix

// pll data
data = LC72131_SNS | LC72131_XS |
pgm_read_byte(ref_data + rx_freq_step);

// send IN1
lc72131_cmd(LC72131_IN1_CMD, divisor, divisor>>8, data);
// calculate band data
data = pgm_read_byte(band_data + rx_mod);
if(rx_unmute) {
data |= LC72131_BAND_UNMUTE;
}

// send IN2
lc72131_cmd(LC72131_IN2_CMD,
data,
0,
LC72131_IFS);

// set SPI reversed bit order back


SPCR &= ~(1<<DORD);
}...

Top

Posted: 11 Jun 2021 - 07:14 PM #2 0 0

clawson
Level: Moderator, 100k
Joined: 18 Jul 2005
Posts: 104859 View Posts
Location: (using avr-gcc in) Finchingfield, Essex, England

By the look of the .aps and .aws files there this looks like a project for Atmel Studio 4 together with the avr-
gcc C compiler.

All the old versions of "Studio " are available here:

https://www.microchip.com/mplab/avr-support/avr-and-sam-downloads-archive
(https://www.microchip.com/mplab/avr-support/avr-and-sam-downloads-archive)

You may think that 4.19 looks like the latest "V 4 " and would be the one to go with but trust me, you will
have an easier life if you get 4.18 instead.

(http://www.nongnu.org/avr-libc/user-manual/FAQ.html)

Top

Posted: 11 Jun 2021 - 07:15 PM #3 0 0


clawson
Level: Moderator, 100k
Joined: 18 Jul 2005
Posts: 104859 View Posts
Location: (using avr-gcc in) Finchingfield, Essex, England

PS forgot to say that you might, of course, simply want to migrate this to something like Microchip Studio 7
if you want to move things on a bit by 10+ years.

(http://www.nongnu.org/avr-libc/user-manual/FAQ.html)

Top

Posted: 11 Jun 2021 - 10:42 PM #4 0 0

ki0bk
Level: 10k+ Postman
Joined: 8 Sep 2014
Posts: 10623 View Posts
Location: Over the rainbow


rpz3598
(using ATMEGA8A , if it is necessary)?

Attiny2313A is available, code and pin compatible, so migration to M8 is not required.


https://www.microchip.com/wwwproducts/en/ATTINY2313A
(https://www.microchip.com/wwwproducts/en/ATTINY2313A)
As Cliff suggested, either AS4.18 or best the latest AS7 would be the IDE of choice, although if you prefer a
non-MS OS, then MPLAB x will work on linux or Mac.
Either IDE is downloadable from MicroChip
Jim

FF = PI > S.E.T

Top

Posted: 12 Jun 2021 - 03:15 AM #5 0 0

awneil
Level: 10k+ Postman
Joined: 2 Jul 2005
Posts: 23038 View Posts
Location: Basingstoke, Hampshire, UK
“ ki0bk
the latest AS7

is now called Microchip Studio 7:

https://www.microchip.com/en-us/development-tools-tools-and-software/microchip-studio-for-avr-and-
sam-devices (https://www.microchip.com/en-us/development-tools-tools-and-software/microchip-studio-
for-avr-and-sam-devices)

Top Tips:
1. How to properly post source code - see: http://www.avrfreaks.net/comment/2153911#comment-2153911
(http://www.avrfreaks.net/comment/2153911#comment-2153911) - also how to properly include images/pictures
2. "Garbage " characters on a serial terminal are (almost?) invariably due to wrong baud rate -
see: https://learn.sparkfun.com/tutorials/serial-communication (https://learn.sparkfun.com/tutorials/serial-
communication)
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed
you expected
4. Difference between a crystal, and a crystal oscillator: http://www.avrfreaks.net/comment/2204401#comment-2204401
(http://www.avrfreaks.net/comment/2204401#comment-2204401)
5. When your question is resolved, mark the solution: http://www.avrfreaks.net/comment/2198746#comment-2198746
(http://www.avrfreaks.net/comment/2198746#comment-2198746)
6. Beginner's "Getting Started " tips: http://www.avrfreaks.net/comment/2079906#comment-2079906
(http://www.avrfreaks.net/comment/2079906#comment-2079906)

Top

Author Posted: 11 Jul 2021 - 04:04 AM Last Updated: 11 Jul 2021 - 02:55 PM #6 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts
//lc72131.h
#define F_CPU 16000000UL

//#include <stdio.h>
//#include <stdlib.h>
//#include <stdbool.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>

#define LC72131_PORT PORTD


#define LC72131_PIN PIND
#define LC72131_DDR DDRD

#define LC72131_CE PD7 //out


#define LC72131_CL PD6 //out
#define LC72131_DI PD5 //out
#define LC72131_DO PD3 //in , or not used for DI,CL,CE only

#define IF1_FM 10700


#define IF1_AM 10710 //or 455 ; 465
#define FrefFM 5 // step=2*5 kHz, fref= 5 kHz , divider by 2 is turned on ,
#define FrefAM_HS 1 //1kHz, fref= 1 kHz, divider by 2 is turned off , using sw
#define FrefAM_LS 1 // 1 kHz, fref= 1 kHz, divider by 2 is turned off , swallow

//R3=1 ;R2=0 ;R1=1 ;R0=0 ; fref=5 kHz FM


//R3=1 ;R2=0 ;R1=1 ;R0=1 ; fref=1 kHz AM
#define RDD_FM_4k5 0xA2 //R3=1,R2=0, R1=1,R0=0 ;; XS=0,CTE=0, DVS=1, SNS=0
#define RDD_FM_7k2 0xAA //R3=1,R2=0, R1=1,R0=0 ;; XS=1,CTE=0,DVS=1, SNS=0
#define RDD_AM_HS_4k5 0xB1 //R3=1,R2=0, R1=1,R0=1;; XS=0,CTE=0, DVS=0, SNS=1
#define RDD_AM_HS_7k2 0xB9 //R3=1,R2=0, R1=1,R0=1;; XS=1,CTE=0, DVS=0, SNS=1
#define RDD_AM_LS_4k5 0xB0 //R3=1,R2=0, R1=1,R0=1;; XS=0,CTE=0, DVS=0, SNS=0 ,
#define RDD_AM_LS_7k2 0xB8 //R3=1,R2=0, R1=1,R0=1;; XS=1,CTE=0, DVS=0, SNS=0 ,
#define BAND_FM 0 // 10...160 MHz
#define BAND_AM_LS 1 // 2 ...40 MHz
#define BAND_AM_HS 2 // 0.5... 10 MHz
#define DEFAULT_FREQ 103700

#define DEFAULT_BAND 0
#define DEFAULT_MODE 0

#define FM_STEREO_MODE 0
#define FM_MONO_MODE 1
#define MW_MONO_MODE 2
/*
DVS ;SNS; LSB Divisor setting (N) Actual divisor
1 ;* ; P0 272 to 65535 Twice the value of the setting
0 ; 1 ; P0 272 to 65535 The value of the setting
0 ;0 ; P4 4 to 4095 The value of the setting

DVS ; SNS Input pin Input frequency range


1 ; * ; FMIN 10 to 160 MHz
0 ; 1 ; AMIN 2 to 40 MHz
0 ;0 ; AMIN 0.5 to 10 MHz
R3; R2; R1; R0; Reference frequency (kHz)
0 ;0 ;0 ;0 ;100
0 ;0 ;0 ;1 ;50
0 ;0 ;1 ;0 ;25
0 ;0 ;1 ;1 ;25
0 ;1 ;0 ;0 ;12.5
0 ;1 ;0 ;1 ;6.25
0 ;1 ;1 ;0 ;3.125
0 ;1 ;1 ;1 ;3.125
1 ;0 ;0 ;0 ;10 *
1 ;0 ;0 ;1 ;9 *
1 ;0 ;1 ;0 ;5 *
1 ;0 ;1 ;1 ;1 *
1 ;1 ;0 ;0 ;3
1 ;1 ;0 ;1 ;15
1 ;1 ;1 ;0 ;PLL INHIBIT + Xtal OSC STOP
1 ;1 ;1 ;1 ;PLL INHIBIT
*/

void LC72131_Send ( uint8_t Data )


{
// send Data byte from LSB to MSB to DI of the LC72131
uint8_t i;
for ( i = 0; i < 8; i++ )
{
//send bit0, bit1, bit2,...bit 7
if ((Data & 0x01)==0) { LC72131_PORT&=~(1<<LC72131_DI) ; } else { LC72131_PORT|=
Data =( Data >> 1);
_delay_us(3);
LC72131_PORT|=(1<<LC72131_CL);
_delay_us(3);
LC72131_PORT&= ~(1<<LC72131_CL );
_delay_us(3);
}
return;
}

uint8_t LC72131_Read ()
{
// read data into the byte from DO of the LC72131 bus to the MCU
uint8_t i, Data=0;
for ( i = 0; i < 8; i++ )
{
LC72131_PORT|=(1<<LC72131_CL);
Data = (Data >> 1);
if ((LC72131_PIN&(1<<LC72131_DO))!=0 ) {Data |=0x80 ; }
LC72131_PORT&= ~(1<<LC72131_CL );
_delay_us(2);
}
return (uint8_t)( Data );
}

void LC72131_SendDivToPLL(uint16_t divisor, uint8_t RDD)


{
//send to PLL
LC72131_PORT&=~(1<<LC72131_CE); //CE=0
LC72131_Send(0x28); //send address for IN1 mode
LC72131_PORT|=(1<<LC72131_CE) ; //CE=1
_delay_us(2);
LC72131_Send((uint8_t)(divisor&0x00FF)); // Lowbyte(divisor), P7_P0
LC72131_Send((uint8_t)(divisor>>8)); // Highbyte(divisor), P15_P8
LC72131_Send(RDD);//R3_R2_R1_R0_XS_CTE_DVS_SNS
LC72131_PORT&=~(1<<LC72131_CE); //CE=0
return;
}

void LC72131_SetBand_Mode(uint8_t mode )


{

//Set nBO4_1 by lookup table for circuit


uint8_t B4_1_IO=0xF0;

if (mode==0){ B4_1_IO=0b11000000; } //FM Stereo


if (mode==1){ B4_1_IO=0b01000000; } //FM Mono
if (mode==2){ B4_1_IO=0b00100000; } // AM Mono

LC72131_PORT&=~(1<<LC72131_CE); //CE=0
LC72131_Send(0x29); //send address for IN2 mode
LC72131_PORT|=(1<<LC72131_CE) ; //CE=1
_delay_us(2);
// BO4 BO3 BO2 BO1 IO2 IO1 IOC2 IOC1 Data=1 Bx=1
// IOC2=0-> nIO2 input mode , IOC2=1 -> nIO2 output mode
// IOC1=0-> nIO1 input mode , IOC1=1 -> nIO1 output mode
// IO2=1 -> nIO2=low, IO2=0-> nIO2=Z,
// IO1=1 -> nIO1=low, IO1=0-> nIO1=Z
// BOn=1 -> nBOn=low, BOn=0 -> nBOn=Z
//selectIO2=0,IO1=0, IOC2=0, IOC1=0
// (BO4_BO3_BO2_BO1<<4)|(IO2_IO1_IOC2_IOC1 =0x00)

LC72131_Send( B4_1_IO);

//DZ1_DZ0=10 DZC; 00=DZA, 01=DZB, 10 =DZC, 11 =DZD, DZA < DZB < DZC < DZD
//UL1_UL0=11 0E is extended by 1 to 2 ms
//DOC2...DOC0=000 DO pin state open
//DNC=0
// DZ1_DZ0_UL1_UL0_DOC2_DOC1_DOC0_DNC //0xB2 or B0
LC72131_Send(0xB0);

//TEST2_TEST1_TEST0=000
//IFS=1 (normal) , 0 sensitivity 10...30 mV
//DLC=0 normal, 1=Forced Low
//TBC=0
//GT1_GT0=00 4us ; 01 =8 us; 10 =32 us; 10 =64 us;
// TEST2_TEST1_TEST0_IFS_DLC_TBC_GT1_GT0; 0x00
LC72131_Send(0x10);
LC72131_PORT&=~(1<<LC72131_CE); //CE=0
return;
}

uint32_t LC72131_ReadData(void)
{

// reading data from the counter of the LC72131


//send to PLL
LC72131_PORT&=~(1<<LC72131_CE); //CE=0
LC72131_Send(0x2A); //send address for OUT mode
LC72131_PORT|=(1<<LC72131_CE) ; //CE=1
_delay_us(2);
uint8_t RD0=LC72131_Read(); // I2;I1;0; UL; C19;C18;C17;C16
uint8_t RD1=LC72131_Read(); // C15;C14;C13;C12;C11;C10;C9;C8
uint8_t RD2=LC72131_Read(); // C7;C6;C5;C4;;C3;C2;C1;C0;;
LC72131_PORT&=~(1<<LC72131_CE); //CE=0

//I2 nIO2 pin state 0-Low, 1-High


//I1 nIO1 pin state 0-Low, 1-High
//UL 0- unlocked , locked or detection stop mode
//C19-C0 counter , C0 LSB
return (uint32_t)(((uint32_t)RD0<<16)|(RD1<<8)|RD2);
}

// set freq LC72131


void LC72131_SetPLL_Freq(uint32_t Freq, uint8_t band )
{
uint8_t RDD=0xA2;
uint16_t divisor=0x07DE;
if (band==BAND_FM)
{

//divisor must be from 272 to 65535


divisor=(uint16_t)((Freq+IF1_FM)>>1)/FrefFM ; //(2*5 kHz)
//DVS=1, SNS=0, FM In ,
//R3=1 ;R2=0 ;R1=1 ;R0=0 ; fref=5 kHz FM
//R3=1,R2=0, R1=1,R0=0, XS=0,CTE=0, DVS=1, SNS=0 , 4.5 MHz
RDD=0xA2 ;//RDD_FM_4k5 ;

}
else
if (band==BAND_AM_HS)
{
//divisor must be from 272 to 65535
divisor=(uint16_t)(Freq+IF1_AM )/FrefAM_HS ;
//DVS=0, SNS=1, AMIN In HS
// fref=1 kHz AM , step 1 kHz
//R3=1,R2=0, R1=1,R0=1, XS=0,CTE=0, DVS=0,SNS=1 , 4.5 MH
RDD=0xB1; //RDD_AM_HS_4k5;
}
else
if (band==BAND_AM_LS)
{
//divisor must be from 4 to 4095
divisor=(uint16_t)(Freq+IF1_AM )/FrefAM_LS ;
divisor=(uint16_t)(divisor<<4); //load LSB from 4 bit ,
//DVS=0, SNS=0, LS AM In
// fref=1 kHz AM , step 1 kHz
//R3=1,R2=0, R1=1,R0=1, XS=0,CTE=0, DVS=0, SNS=0 , 4.5 MHz
RDD=0xB0;//RDD_AM_LS_4k5 ;
//for 0x0091 ->0x0910
//* * * * ;;'1' rev ;;'9' rev ;; '0' rev ;;
//* ; * ; *; *;;1 ;0 ;0 ;0 ;;1 ;0 ; 0 ; 1 ;; 0 ; 0 ; 0 ;0 ;;0; 0 ; - ;-0 ;;0
//P0;P1;P2;P3 ;;P4;P5;P6;P7;;P8;P9;P10;P11;;P12;P13;P14;P15;; SNS ; DVS ; CTE ;XS;
}
LC72131_SendDivToPLL(divisor, RDD );
return;
}

void InitLC72131()
{
// 0x28 -divider (IN1 mode) addr
// 0x29 -control (IN2 mode) addr
// 0x2A - output (OUT mode) addr
// may be in the main program
LC72131_DDR|=(1<<LC72131_CE)|(1<<LC72131_CL)|(1<<LC72131_DI );
LC72131_DDR&=~(1<<LC72131_DO );
LC72131_PORT&=~(1<<LC72131_CE)|(1<<LC72131_CL)|(1<<LC72131_DI );

LC72131_SetBand_Mode(DEFAULT_MODE );
LC72131_SetPLL_Freq(DEFAULT_FREQ, DEFAULT_BAND);
return;
}

/*
DVS=1,SNS=*(0)
FMIn-> [:2] -> [SW count 4 bit]->[12bit counter]->Fvco/N
Fvco/N ->{PD}-> 0E
fref ->{ }
Fvco=fref*(N*2), set divisor N=272...65535 10..160 MHz

DVS=0,SNS=1
AMIn -> [SW count 4 bit]->[12bit counter]->Fvco/N
Fvco/N ->{PD}-> 0E
fref ->{ }
Fvco=fref*N , N= 272 t0 65535

DVS=0,SNS=0
AMIn ->[12bit counter]->Fvco/N
Fvco/N ->{PD}-> 0E
fref ->{ }

Fvco=fref* N ,N= 4 to 4095

XS=0 4.5 kHz, XS=1 7.2 MHz


CTE=1 Counter start, CTE=0 Counter reset

The LC72131 inputs and outputs data using the Sanyo CCB (computer control bus) aud
LSI adopts an 8-bit address format CCB.

B0;B1;B2;B3;;A0;A1;A2;A3
0x82
0;0;0;1;;0;1;0;0; ;; SendHighNubble(0x82),SendLowNibble(0x82)
DI:(Address) B0;B1;B2;B3;A0;A1;A2;A3; (first data In)P0;P1...

IN1 mode
DI control
ADDRESS 82 ;; data
rev 8 ; rev 2 ;
0;0;0;1;0;1;0;0;;P0;P1;P2;P3;;P4;P5;P6;P7;;P8;P9;P10;P11;;P12;P13;P14;P15;; SNS ;

SendNibble(HighNibble(0x82)) ; SendNibble(LowNibble(0x82))
SendNibble(P3_P0) ; SendNibble(P7_P4) //P7...P0
SendNibble(P11_P8) ; SendNibble(P15_P12)
SendNibble(XS_CTE_DVS_SNS); SendNibble(R3_R2_R1_R0)

or

SendByte(0x28);
SendByte(P7_P0); //Lowbyte(divisor), for example divisor=0x07DE
SendByte(P15_P8);//Highbyte(divisor)
SendByte(R3_R2_R1_R0_XS_CTE_DVS_SNS);

IN2 mode
DI control
ADDRESS 92 ;; data
rev 9 ; rev 2 ;
1;0;0;1;0;1;0;0;;IOC1;IOC2;IO1;IO2;;BO1;BO2;BO3;BO4;;DNC;DOC0;DOC1;DOC2;;UL0;UL1;D

// Low Nibble, High Nibble


//SendNibble( HighNibble(0x92) ) ; SendNibble(LowNibble(0x92))
SendNibble( 0x09 ) ; SendNibble( 0x02))
SendNibble(IO2_IO1_IOC2_IOC1) ; SendNibble(BO4_BO3_BO2_BO1)
SendNibble(DOC2_DOC1_DOC0_DNC) ; SendNibble(DZ1_DZ0_UL1_UL0);
SendNibble(DLC_TBC_GT1_GT0); SendNibble(TEST2_TEST1_TEST0_IFS)

or

SendByte(0x29);
SendByte((BO4_BO3_BO2_BO1<<4)|IO2_IO1_IOC2_IOC1 );
SendByte(DZ1_DZ0_UL1_UL0_DOC2_DOC1_DOC0_DNC);
SendByte(TEST2_TEST1_TEST0_IFS_DLC_TBC_GT1_GT0);

OUT Mode
DI control
ADDRESS A2
A rev 2 Rev
0;1;0;1; 0;1;0;0; ;

SendNibble( 0x0A ) ; SendNibble( 0x02))

DO answer
I2;I1;0; UL; C19;C18;C17;C16;;C15;C14;C13;C12;;C11;C10;C9;C8;;C7;C6;C5;C4;;C3;C2;C

SendData(0x2A);// set addr 0xA2 , OUT mode

DATA2= ReadData();// I2;I1;0; UL; C19;C18;C17;C16


DATA1= ReadData();//C15;C14;C13;C12;C11;C10;C9;C8
DATA0= ReadData();//C7;C6;C5;C4;;C3;C2;C1;C0;;
DATA3=(DATA2&0xF0)>>4;
DATA2&=0x0F;

uint32_t data=(DATA2<<16)|(DATA1<<8)|DATA0 ;

1)

FM,50 kHz steps(DVS=1,SNS=*,FMIN selected )


FM RF=90.0 MHz ,IF=10.7 MHz
FMVCO=100.7 MHz
PLL fref=25 kHz , R0=1,R1=1,R2=0,R3=0

divisor=(100700/2)/25kHz=2014=07DE hex
step=2*fref=2*25=50 kHz
reverse bits
'E' rev ;; 'D' rev ;;'7' rev ;; '0' rev ;;
0 ; 1 ; 1; 1;;1 ;0 ;1 ;1 ;;1 ;1 ; 1 ; 0 ;; 0 ; 0 ; 0 ;0 ;;* ; 1 ; - ;-0 ;;
P0;P1;P2;P3 ;;P4;P5;P6;P7;;P8;P9;P10;P11;;P12;P13;P14;P15;; SNS ; DVS ; CTE ;XS;;R

2)
SW, 5 kHz steps(DVS=0,SNS=1,AMIN HS selected )
step= fref= 5 kHz
SW RF=27.75 MHz ,IF=+450 kHz
SW VCO=22.20 MHz
PLL fref=5 kHz , R0=0,R1=14,R2=0,R3=1
divisor=22200kHz/5kHz=4440=1158 hex

reverse bits
'8' rev ;; '5' rev ;;'1' rev ;; '1' rev ;;
0 ; 0 ; 0; 1;;1 ;0 ;1 ;0 ;;1 ;0 ; 0 ; 0 ;; 1 ; 0 ; 0 ;0 ;;1 ; 0 ; - ;-0 ;;0 ;
P0;P1;P2;P3 ;;P4;P5;P6;P7;;P8;P9;P10;P11;;P12;P13;P14;P15;; SNS ; DVS ; CTE ;XS;;R

3)
MW,10 kHz steps(DVS=0,SNS=0,AMIN LS selected )
step= fref= 10 kHz
SW RF=1000 kHz ,IF=+450 kHz
SW VCO=1450 kHz
PLL fref=10 kHz , R0=0,R1=0,R2=0,R3=1
divisor=1450kHz/10kHz(fref)=145=0091 hex
divisor=divisor<<4;

// * * * * ;;'1' rev ;;'9' rev ;; '0' rev ;;


// * ; * ; *; *;;1 ;0 ;0 ;0 ;;1 ;0 ; 0 ; 1 ;; 0 ; 0 ; 0 ;0 ;;0; 0 ; - ;-0 ;;
//P0;P1;P2;P3 ;;P4;P5;P6;P7;;P8;P9;P10;P11;;P12;P13;P14;P15;; SNS ; DVS ; CTE ;XS;

*/

Top

Author Posted: 11 Jul 2021 - 04:12 AM #7 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

I use only nBO4, nBO3,nBO2 (nBO1 and other GPIO pins are reserved, not used in my circuit ) , FMIn, AMI,
CE,DI,CL.
nBO4 - stereo (0- on , for p-n-p transistor , emitter to Vcc , 10..22 k resistor base to nBO4, collector to the
circuit with LED and resistor 1 k (TA7343AP) ),
nBO3 - FM tuner (0 -on , for p-n-p transistor to Vcc with 10...22 k resistor (base-> nBO3) ),
nBO2 - FM tuner (0 -on , for p-n-p transistor , emitter to Vcc with 10...22 k resistor (base-> nBO1) )
Top

Author Posted: 11 Jul 2021 - 10:40 AM #8 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Simple runner ( fix some bugs ):


/*

Pins:
PD0 btn0 (to GND)
PD1 btn1 (to GND)
PD2 btn2 (to GND)

*/

// setup IDE proc. presets and type( ATTiny2313A-20PU,4MHZ)

#define F_CPU 16000000UL


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdint.h>
#include <math.h>
#include "lcd.h "
#include "lc72131.h "

#define BTNPORT PINC


#define BTN0_PIN PD2
#define BTN1_PIN PD3
#define BTN2_PIN PD4

#define BTN_INCF 0b00000100 // BTN0_PIN


#define BTN_DECF 0b00001000 //BTN1_PIN
#define BTN_DECSTEP 0b00010100 // ( BTN2_PIN | BTN0_PIN )
#define BTN_INCTEP 0b00011000 // (BTN2_PIN | BTN1_PIN )
#define BTN_READ 0b00001100 // (BTN0_PIN | BTN1_PIN)
#define BTN_SAVE 0b00010000//BTN2_PIN

#define Ndigits 6

#define ControlByte 0b10100011 /* 0b10100000 for 25kHz or 0b10000000 for 100 k

#define IF_MODE 1 //fosc=fsignal+fif

#define Freq_min 87500


#define Freq_max 110000
#define Freq_default 103700
#define Fif 10700
#define Freq_Step 10

uint32_t Freq=Freq_default;

#define Fref Freq_Step


uint32_t DivStep =Freq_Step;
uint8_t i;

uint8_t DisplayBuffer[6];
uint8_t Comma;
uint8_t Pos=3;
uint8_t BTNS=0;

/*
ISR(TIMER0_OVF_vect)
//interrupt[TIM0_OVF] void timer0_ovf_isr(void)
{
LedSend();
return;
}
*/

unsigned char EEPROM_read(unsigned int uiAdress)


{
asm( "cli ");
while (EECR&(1<<EEWE)) { ; }// Spin-lock until EEPROM finishes prev write
// Setup address register
EEAR=uiAdress;
// Start read
EECR|=(1<<EERE);

return EEDR;
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)


{
asm( "cli ");
if (ucData == EEPROM_read(uiAddress)) { return; }
// Spin-lock until EEPROM finishes prev write
while( EECR&(1<<EEWE) ) { ; }
// Setup addr and data registers
EEAR=uiAddress;
EEDR=ucData;
// Enable EEPROM write
EECR|=(1<<EEMWE);
// Start EEPROM write
EECR|=(1<<EEWE);
return;
}

unsigned char Hdigit=0;

void Data_Decoding(void)
{
asm( "cli ");

Hdigit= (unsigned char) ( ( Freq/100000) &0xff) ; // 100800


if(Hdigit==0 ) { Hdigit =0x20 ; }

DisplayBuffer[0]=(unsigned char) Hdigit|0x30;


DisplayBuffer[1]=(unsigned char) ((Freq/10000)%10) |0x30; // (freq/10000) mod 10
DisplayBuffer[2]=(unsigned char) ((Freq/1000)%10)|0x30 ;
DisplayBuffer[3]=(unsigned char) ((Freq/100)%10)|0x30;
DisplayBuffer[4]=(unsigned char) ((Freq/10)%10)|0x30;
DisplayBuffer[5]=(unsigned char) ((Freq/1)%10)|0x30;

Comma = 2;

asm( "sei ");


return;
}

void PrintFreq()
{
LCDsendCommand( 0x80);

for(i=0;i<6;i++)
{
//if (i==Comma) {LCDsendCommand( 0x80+i+1); LCDsendChar('.');}

LCDsendChar(DisplayBuffer[i]);
}
LCDsendChar('k');
LCDsendChar('H');
LCDsendChar('z');
LCDsendCommand( 0x80+Pos);
LCDsendCommand(0x0E) ;
}

void InitPorts( void )


{
DDRD = 0b11100010; // PD0 RX,PD1 TX , PD2 Int0 RDCL, PD3 Int 1 Q, PD4 RDDA,
DDRB = 0b00111111; //PB0-PB3 D0-D4 , PB4 RS, PB5 E
DDRC = 0b00000000; //PC0,PC1 AIN or input, PC2,PC3 PC4 Input
PORTC = 0b00011100;
//LC72131_DDR|=(1<<LC72131_CE)|(1<<LC72131_CL)|(1<<LC72131_DI );
//LC72131_DDR&=~(1<<LC72131_DO );
//LC72131_PORT&=~(1<<LC72131_CE)|(1<<LC72131_CL)|(1<<LC72131_DI );

LCD_init();
LCD_cursor(0);

return;
}
/*
void Timer0_Init( void )
{
TCCR0A = 0b00000000;
TCCR0B = 0b00000011; //clkI/O/ 64 (From prescaler)
TCNT0 = 0b00000000;
TIMSK = 0b00000010; // Разрешено прерывание по переполнению
return;
}
*/

void SaveToMemory(void)
{
asm( "cli ");

EEPROM_write(0,DisplayBuffer[0]); //1
EEPROM_write(1,DisplayBuffer[1]); //0
EEPROM_write(2,DisplayBuffer[2]); //3
EEPROM_write(3,DisplayBuffer[3]); //7
EEPROM_write(4,DisplayBuffer[4]); //0
EEPROM_write(5,DisplayBuffer[5]); //0
_delay_ms(1000);
}

void ReadMemory(void)
{

asm( "cli ");


Freq=(EEPROM_read(0)*100000)+(EEPROM_read(1)*10000)+(EEPROM_read(2)*1000)
+(EEPROM_read(3)*100 )+(EEPROM_read(4)*10 )+(EEPROM_read(5) );

if((Freq>Freq_max)||(Freq<Freq_min)) { Freq=Freq_default;}
_delay_ms(300);

return;
}

void DecodeCurPos(unsigned char Pos)


{

switch(Pos)
{
case 0:
DivStep=100000; //x03.700
break;
case 1:
DivStep=10000; //1x3.700
break;
case 2:
DivStep=1000; //10x.700
break;

case 3:
DivStep=100; //103.x00
break;

case 4: //103.7x0
DivStep=10;

case 5: //103.70x
DivStep=Freq_Step;

return;
}

void CursorRight()
{
asm( "cli ");
if(Pos>1) {Pos--;}
DecodeCurPos(Pos);
PrintFreq();

_delay_ms(800);
return;
}

void CursorLeft(void)
{
asm( "cli ");
if(Pos<Ndigits-1) {Pos++;}
DecodeCurPos(Pos);
PrintFreq();
_delay_ms(800);

return;
}

void IncFreq(void)
{

Freq +=DivStep;

if(Freq>Freq_max) { Freq = Freq_min; }

Data_Decoding();
LC72131_SetPLL_Freq(Freq,BAND_FM );
PrintFreq();
_delay_ms(300);

return;
}

void DecFreq(void)
{

Freq-=DivStep;
if(Freq <Freq_min) { Freq= Freq_max; }
Data_Decoding();

LC72131_SetPLL_Freq(Freq, BAND_FM );
PrintFreq();

_delay_ms(300);

return;
}

void Control(void)
{

BTNS= ((~(PINC))&0b00011100) ;
switch(BTNS)

{
case BTN_READ:
ReadMemory();
break;

case BTN_SAVE:
SaveToMemory();
break;

case BTN_INCTEP:
CursorLeft();
break;

case BTN_DECSTEP:
CursorRight();
break;

case BTN_INCF:
IncFreq();
break;
case BTN_DECF:
DecFreq();
break;

default:
break;

}
//asm( "sei ");
return;
}

int main(void)
{
InitPorts( );
InitLC72131();
LC72131_SetBand_Mode(FM_STEREO_MODE);
Comma = 2;
DecodeCurPos(Pos);

Freq=Freq_default;

ReadMemory();

LC72131_SetPLL_Freq(Freq,BAND_FM );
Data_Decoding();
PrintFreq();
//Timer0_Init();

//asm( "sei ");

while(1)
{
Control();
}

}
//lcd.h
//*****************************************************************************
//fix some bugs with initialising and delays

#define F_CPU 16000000UL


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
//#include "customchars.h "

//******************************************
#define LCD_4bit
//***********************************************

#define LCD_RS 4 //define MCU pin connected to LCD RS


//#define LCD_RW 6 //define MCU pin connected to LCD R/W ,not used ,
#define LCD_E 5 //define MCU pin connected to LCD E

//D0-D3 not used for 4 bit mode

#define LCD_D4 0 //define MCU pin connected to LCD D4


#define LCD_D5 1 //define MCU pin connected to LCD D5
#define LCD_D6 2 //define MCU pin connected to LCD D6
#define LCD_D7 3 //define MCU pin connected to LCD D7

#define LDP PORTB //define MCU port connected to LCD data pins
#define LCP PORTB //define MCU port connected to LCD control pins
#define LDDR DDRB //define MCU direction register for port connected to LCD
#define LCDR DDRB //define MCU direction register for port connected to LCD

#define LCD_CLR 0 //DB0: clear display


#define LCD_HOME 1 //DB1: return to home position
#define LCD_ENTRY_MODE 2 //DB2: set entry mode
#define LCD_ENTRY_INC 1 //DB1: increment
#define LCD_ENTRY_SHIFT 0 //DB2: shift
#define LCD_ON_CTRL 3 //DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY 2 //DB2: turn display on
#define LCD_ON_CURSOR 1 //DB1: turn cursor on
#define LCD_ON_BLINK 0 //DB0: blinking cursor
#define LCD_MOVE 4 //DB4: move cursor/display
#define LCD_MOVE_DISP 3 //DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT 2 //DB2: move right (0-> left)
#define LCD_FUNCTION 5 //DB5: function set
#define LCD_FUNCTION_8BIT 4 //DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3 //DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2 //DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM 6 //DB6: set CG RAM address
#define LCD_DDRAM 7 //DB7: set DD RAM address
// reading:
#define LCD_BUSY 7 //DB7: LCD is busy
#define LCD_LINES 2 //visible lines
#define LCD_LINE_LENGTH 16 //line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR 0x00
#define LCD_LINE1_DDRAMADDR 0x40
#define LCD_LINE2_DDRAMADDR 0x14
#define LCD_LINE3_DDRAMADDR 0x54

#define DataMask (1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4)


#define MapHighNibble(x) ( (((x) & 0xF0) >> 4 ) << LCD_D4 )
#define MapLowNibble(x) ( (((x) & 0x0F) & 0x0F) << LCD_D4 )

/*******************************************/

void lcd_enable(void)
{
LCP |= (1<<LCD_E );
_delay_us(40);
LCP &= ~(1<<LCD_E );
_delay_us(40);
}

void LCDsendChar(uint8_t ch) //Sends Char to LCD


{
//4 bit part
LDP=(ch>>4)|(1<<LCD_RS);
lcd_enable();
LDP=(ch&0x0f)|(1<<LCD_RS);
lcd_enable();
LCP &= ~(1<<LCD_RS );
}

void LCDsendCommand(uint8_t cmd) //Sends Command to LCD


{
//4 bit part
LDP=(cmd>>4) ;
lcd_enable();
LDP=(cmd &0x0f);
lcd_enable();

void LCD_init (void)


{
LDP=0x00;
LCP=0x00;
_delay_ms(20);
LDDR |= (1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_E |1<<LCD_RS) ;
LDP =0b00000011; // 0x03 ; //RS=0
lcd_enable(); //1 set RS=0, RnV=0 Data74=0011(0x03),wait >4,1
_delay_ms(5);
lcd_enable(); //2 set RS=0, RnV=0 Data74=0011(0x03), wait >100
_delay_ms(1);
lcd_enable(); //3 set RS=0, RnV=0 Data74=0011(0x03),
_delay_ms(1);

_delay_ms(15); //Wait before LCD activation

LDP= 0b00000010; //0x02 ; //RS=0, 0x02 Set interface to be 4


_delay_ms(1);
lcd_enable(); //4bit mode
_delay_ms(1);

LCDsendCommand(0x28); //Control Matrix @ 4-Bit, number of display li


LCDsendCommand(0x08);
LCDsendCommand(0x01); //Clear display
// _delay_ms(5);
LCDsendCommand(0x0c); //Display ON Cursor OFF
_delay_ms(20);
LCDsendCommand(0x06); //Auto Increment cursor
LCDsendCommand(0x0E); //Turn on visible underline cursor
LCDsendCommand(0x02); //Cursor at home position
// SetCGRAMUserChars();
_delay_ms(20);

//fix for R/W =0, 4bit

void LCD_clear(void) { LCDsendCommand(0x01); _delay_ms(20); }//Clears L


void LCD_home(void){ LCDsendCommand(0x02); }//LCD cursor home

void LCD_goto(uint8_t y, uint8_t x)


{
register uint8_t DDRAMAddr=DDRAMAddr;
// remap lines into proper order

if(y==1){ DDRAMAddr = LCD_LINE0_DDRAMADDR+x-1; LCDsendCommand(1<<LCD_DDRA


if(y==2) { DDRAMAddr = LCD_LINE1_DDRAMADDR+x-1; LCDsendCommand(1<<LCD_DDRA
//default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x-1;

void LCDstring(uint8_t* data, uint8_t nBytes) //Outputs string to LCD


{
register uint8_t i;
if (!data) { return; } // check to make sure we have a good pointer
for(i=0; i<nBytes; i++){ LCDsendChar(data[i]);} // print data
}

void LCD_cursor(uint8_t on){ if (on == 0) { LCDsendCommand(0x0C); } else { LC

//Copies string from flash memory to LCD at x y position


//const uint8_t welcomeln1[] PROGMEM='AVR LCD DEMO\0';
//CopyStringtoLCD(welcomeln1, 3, 1);
/*
void CopyStringtoLCD(const uint8_t *FlashLoc, uint8_t x, uint8_t y)
{
uint8_t i;
LCDGotoXY(x,y);
for(i=0; (uint8_t) pgm_read_byte(&FlashLoc[i]); i++) { LCDsendChar((uint8_t)pgm_re
}
*/

//void LCDshiftLeft(uint8_t n) { uint8_t i; for ( i=0; i<n; i++){ LCDsendCommand(0


//void LCDshiftRight(uint8_t n){ uint8_t i;for ( i=0;i<n;i++){ LCDsendCommand(0x18
//void LCDcursorOn(void){ LCDsendCommand(0x0E); } //displays LCD cursor
//void LCDcursorOnBlink(void) { LCDsendCommand(0x0F); } //displays LCD blinking
//void LCDcursorOFF(void) { LCDsendCommand(0x0C); } //turns OFF cursor
//void LCDblank(void) { LCDsendCommand(0x08); } //blanks LCD
//void LCDvisible(void){ LCDsendCommand(0x0C);}//Shows LCD
//void LCDcursorLeft(uint8_t n) { uint8_t i;for ( i=0;i<n;i++){ LCDsendCom
//void LCDcursorRight(uint8_t n) {uint8_t i; for ( i=0;i<n;i++){ LCDsendCo

/*
Power on

Wait for more than 15 ms


after VCC rises to 4.5 V
1)
RS ; R/nW ;DB7 ;DB6; DB5; DB4
0 ; 0 ; 0 ; 0 ; 1 ; 1

2) Wait for more than 4.1 ms


RS ; R/nW ;DB7 ;DB6; DB5; DB4
0 ; 0 ; 0 ; 0 ; 1 ; 1

3)
Wait for more than 100 µs
RS ; R/nW ;DB7 ;DB6; DB5; DB4
0 ; 0 ; 0 ; 0 ; 1 ; 1

6) Wait for more than 4.1 ms


RS ; R/nW ;DB7 ;DB6; DB5; DB4
0 ; 0 ; 0 ; 0 ; 1 ; 1

7)
RS ; R/nW ;DB7 ;DB6; DB5; DB4
0 ; 0 ; 0 ; 0 ; 1 ; 0
0 ; 0 ; 0 ; 0 ; 1 ; 0
0 ; 0 ; N ; F ; * ; *
0 ; 0 ; 0 ; 0 ; 0 ; 0
0 ; 0 ; 1 ; 0 ; 0 ; 0
0 ; 0 ; 0 ; 0 ; 0 ; 0
0 ; 0 ; 0 ; 0 ; 0 ; 1
0 ; 0 ; 0 ; 0 ; 0 ; 0
0 ; 0 ; 0 ; 1 ; I/D ; S

*/

LCD library (asm )


; LCD Module commands
;

;CLR_DISP - clears all display, and cursor home to addr 0


.equ CLR_DISP = 0x01 ; Clear the Displa

;RTN_HOME - cursor home and display unshifted, DDRAM unchanged


.equ RTN_HOME = 0X02

;ENTRY_... - sets entry mode, S = display shift on, INC / DEC cursor move dir
.equ ENTRY_DEC = 0x04
.equ ENTRY_DEC_S = 0x05
.equ ENTRY_INC = 0x06
.equ ENTRY_INC_S = 0x07

;DISP_... - Display on / off control, C = cursor ON, B = chr pos blink


.equ DISP_OFF = 0x08 ; Display off
.equ DISP_ON = 0x0C ; Display
.equ DISP_ON_B = 0x0D ; Display
.equ DISP_ON_C = 0x0E ; Display
.equ DISP_ON_BC = 0x0F ; Display on, Curs

;SHIFT_... - Cursor & Display shift, S = Display, C = cursor, L = Left, R = Right


.equ SHIFT_C_L = 0x10
.equ SHIFT_C_R = 0x14
.equ SHIFT_S_L = 0x18
.equ SHIFT_S_R = 0x1C

;FUNC_... - Function set, ( 4 bit, 2 lines, 5 x 7 dots)


.equ FUNC_SET = 0x28

;
.equ CURS_RGT = 0x93
.equ DD_RAM_ADDR = 0x80 ; Least Significant 7-bit are for address
.equ DD_RAM_UL = 0x80 ; Upper Left coner of the Display
;
;
;
;*******************************************************************
;* The LCD Module Subroutines *
;*******************************************************************
;

.def LCD_REG1 =r29 ; register 1 for LCD routine

;*******************************************************************
;LCD Wait
;*******************************************************************

;LCDWait1: nop
; nop
; nop
; nop
; nop
; nop
; ret

; Assembly code auto-generated


; by utility from Bret Mulvey
; Delay 633 cycles
; 39us 562 1/2 ns
; at 16 MHz
LCDWait40us:

ldi r29, 213 ;211 , fix for LCD


L1_Wait40us: dec r29
brne L1_Wait40us

ret

; Assembly code auto-generated


; by utility from Bret Mulvey
; Delay 15 993 cycles + 3 cycles rcall+ 4 cycles ret
; 1ms at 16 MHz

lcd_delay1ms:
ldi r26, 21
ldi r27, 196
L1_1ms:
dec r27
brne L1_1ms
dec r26
brne L1_1ms
ret

; Assembly code auto-generated


; by utility from Bret Mulvey
; Delay 79 993 cycles
; 4ms 999us 562 1/2 ns
; at 16 MHz
; at 16 MHz + 3 cycles rcall+ 4 cycles ret

lcd_delay5ms:

ldi r26, 104


ldi r27, 226
L1_5ms:
dec r27
brne L1_5ms
dec r26
brne L1_5ms
ret

lcd_delay20ms:
rcall lcd_delay5ms
rcall lcd_delay5ms
rcall lcd_delay5ms
rcall lcd_delay5ms
ret

lcd_delay50ms:
rcall lcd_delay20ms
rcall lcd_delay20ms
rcall lcd_delay5ms
rcall lcd_delay5ms
ret
lcd_delay_loop:
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
rcall lcd_delay50ms
ret

;*******************************************************************
;* This routine checks the busy flag, returns when not busy *
;*******************************************************************

;LCDBusy_Check:

; ldi LCD_REG1, 0b00001111 ; Set high nibble to input


; out LCDTRIS, LCD_REG1
; clr LCD_REG1 ; remove pull-ups on data nibble / clear controls
; out LCDOUT, LCD_REG1

; sbi LCDOUT, R_W ; Setup to read busy flag


; sbi LCDOUT, E ; Set E high
; rcall LCDWait
; in LCD_REG1, LCDIN ; Read upper nibble busy flag, DDRam addr
; cbi LCDOUT, E ; Set E low

; rcall LCDWait

; sbi LCDOUT, E ; Set E high to get rid of lower nibble


; rcall LCDWait
; cbi LCDOUT, E ; Set E low

; sbrc LCD_REG1, 7 ; Check busy flag, high = busy


; rjmp LCDBusy_Check ; loop if high
; cbi LCDOUT, R_W
; ldi LCD_REG1, 0b11111111
; out LCDTRIS, LCD_REG1 ; set for output
; ret

LCD_Enable:
sbi LCDOUT, E ; toggle E for LCD
rcall LCDWait40us
cbi LCDOUT, E
rcall LCDWait40us
ret

;*******************************************************************
;*LCDSendChar - Sends character to LCD *
;*This routine splits the character into the upper and lower *
;*nibbles and sends them to the LCD, upper nibble first. *
;*******************************************************************

LCDSend_Char:
; rcall LCDBusy_Check ; Wait for LCD to be ready
;rcall LCDWait40us
mov r29, W
swap r29 ; D7-D4 -> PD3-PD0, PD4-PD7 =0
andi r29, 0x0f; Get upper nibble into upper half port
;ori r29, 0x10

out LCDOUT, r29 ; Send data to LCD ; already set LCD to write in busy routin
sbi LCDOUT,RS
rcall LCD_Enable ; saving space - sod readability thou

mov r29, W
andi r29, 0x0f ; Get lower nibble into upper half port
;ori r29,0x10 ; (1<<RS)
out LCDOUT, r29 ; Send data to LCD
sbi LCDOUT, RS ; Set LCD to data mode
rcall LCD_Enable;
cbi LCDOUT,RS
ret

;*******************************************************************
;* SEND_CMD - Sends command to LCD *
;* This routine splits the command into the upper and lower *
;* nibbles and sends them to the LCD, upper nibble first. *
;*******************************************************************

LCDSend_Cmd:
;rcall LCDBusy_Check ; Wait for LCD to be ready
; rcall LCDWait40us
cbi LCDOUT,RS
mov r29, W
swap r29 ; D7-D4 -> PD3-PD0, PD4-PD7 =0
andi r29, 0x0F ; Get upper nibble into upper half port ; LCDREG1= W & 0xf0
out LCDOUT, r29 ; Send data to LCD ; already set LCD to write and ctl ;
rcall LCD_Enable ; saving space - sod readability thou

mov r29, W
andi r29, 0x0F ; Get lower nibble into upper half port
out LCDOUT, r29 ; Send data to LCD ; already set LCD to read in busy routine
rjmp LCD_Enable
ret

;*************************************************************************
;Display routines
;*************************************************************************
LCDdisplay_init:

clr W
out LCDOUT,W
ldi W, 0b00111111;
out LCDTRIS ,W
rcall lcd_delay50ms ;1) power on , delay>50 ms

ldi W,0x03
out LCDOUT, W ;Init LCD
rcall LCD_Enable; ; 2) RS=0, RnW=0 data= 0x03 , then delay >4.1 ms
rcall lcd_delay5ms
rcall LCD_Enable; ; 3) RS=0, RnW=0 data= 0x03 , then delay > 100 us
rcall lcd_delay1ms

rcall LCD_Enable; ;4) RS=0, RnW=0 data= 0x03 , then delay > 100 us
rcall lcd_delay1ms
;in the 8 bit mode
ldi W,0x02 ;5) RS=0, RnW=0 data= 0x02 , then del
out LCDOUT, W
rcall LCD_Enable;
rcall lcd_delay1ms

;in the 4 bit mode ; 6) 2h then 8h , then delay>53 us or check BF


ldi W,0x02
out LCDOUT, W
rcall LCD_Enable;
ldi W,0x08
out LCDOUT,W ;Init LCD
rcall LCD_Enable;
rcall lcd_delay1ms

ldi W,0x08 ; display off then wait >53 us or check BF


rcall LCDSend_Cmd

ldi W, 0x01
rcall LCDSend_Cmd ; clear display then wait >3 ms or check BF
rcall lcd_delay5ms

ldi W, 0x0C
rcall LCDSend_Cmd ; display on

ldi W,0x06
rcall LCDSend_Cmd ; input mode Auto Increment cursor

; ldi W,0x0E
; rcall LCDSend_Cmd ;

ldi W,0x02
rcall LCDSend_Cmd ; Cursor at home position

rcall lcd_delay5ms

ret

LCDClear_Display:
ldi W, 0x01
rcall LCDSend_Cmd ; clear display then wait >3 ms or check BF
rcall lcd_delay5ms
ret

Attachments: synt_sketch_test.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTSgAAP)

Top

Author Posted: 11 Jul 2021 - 02:55 PM #9 0 0


rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

fix

#define FrefFM 5 // step=2*5 kHz, fref=5 kHz

Top

Author Posted: 11 Jul 2021 - 02:56 PM #10 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Optimize integrator circuit .

Top

Author Posted: 12 Jul 2021 - 01:01 AM #11 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Fixed bug with EEPROM ( problem with data encoding and loading in the Data_Decoding(),
ReadMemory()and PrintFreq() ). Fixed bug with multiplying .
void Data_Decoding(void)
{
asm( "cli ");

DisplayBuffer[0]=(uint8_t) ((Freq/100000)&0xff) ; // 100800


DisplayBuffer[1]=(uint8_t) ((Freq/10000)%10) ; // (freq/10000) mod 10
DisplayBuffer[2]=(uint8_t) ((Freq/1000)%10) ;
DisplayBuffer[3]=(uint8_t) ((Freq/100)%10) ;
DisplayBuffer[4]=(uint8_t) ((Freq/10)%10) ;
DisplayBuffer[5]=(uint8_t) ((Freq/1)%10) ;
Comma = 2;
//asm( "sei ");
return;
}
...
void PrintFreq()
{
LCDsendCommand( 0x80);
if(DisplayBuffer[0]==0) { LCDsendChar(0x20); } else { LCDsendChar(DisplayBuffer[0]
for(i=1;i<6;i++)
{
LCDsendChar(DisplayBuffer[i]|0x30);
}
LCDsendChar(0x20);
LCDsendChar('k');
LCDsendChar('H');
LCDsendChar('z');

LCDsendCommand( 0x80+Pos);
LCDsendCommand(0x0E) ;
}

...

void ReadMemory(void)
{

asm( "cli ");


uint8_t temp1;
Freq=0;
for(temp1=0; temp1<EEPROM_read(0); temp1++) { Freq+=100000; }
for(temp1=0; temp1<EEPROM_read(1); temp1++) { Freq+=10000; }
for(temp1=0; temp1<EEPROM_read(2); temp1++) { Freq+=1000; }
for(temp1=0; temp1<EEPROM_read(3); temp1++) { Freq+=100; }
for(temp1=0; temp1<EEPROM_read(4); temp1++) { Freq+=10; }
for(temp1=0; temp1<EEPROM_read(5); temp1++) { Freq++; }

if((Freq>Freq_max)||(Freq<Freq_min)) { Freq=Freq_default;}
_delay_ms(300);

return;
}

Attachments: synt_fixed.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTP9AAP)

Top
Author Posted: 17 Jul 2021 - 09:55 AM #12 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

Test edition (ATMEGA8A, 16 MHz , 1602A, RDS(0A,0B,2A,2B, PI), AM, FM for LA1787+TA7343AP(6V) ). Check
and fix some bugs, rewrite some subroutines ( not very fast works with RDS ). Change some values for your
tuner .

Attachments: syntRDS.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTvVAAX), syntRDS


1_0.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTvWAAX)

Top

Author Posted: 23 Jul 2021 - 02:30 AM #13 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

My alternative edition with group type autoselecting (0a/0b , 2a/2b) . Works if bit error ratio in the
decoder is good .

Attachments: syntRDS3.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTvXAAX)

Top

Author Posted: 24 Jul 2021 - 05:59 PM #14 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

An edition with one cursor button and mode switch button, one memory location . But you can create
more than one memory cell for 0x2000+ 0x000...0x1FF, add SSB mode (using nBO1 for SSB oscillator 450
kHz control for band 160 m , for example ) .

Attachments: syntRDS5.zip (/sfc/servlet.shepherd/document/download/0693l00000VHTvYAAX)

Top

Author Posted: 24 Sep 2021 - 09:53 PM #15 0 0


rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

My version for WinAVR , ATMEGA8A-16PU(-PU), 16 MHz osc., FM 64-110 MHz (IF=10.7 MHz), AM/SSB 100
kHz-4MHz (IF1=10.71 MHz, IF2=450 kHz , fixed Losc=10 uH ->8.2uH approx. for 4 MHz (fosc= 14.71 MHz ,
Vt=7.8 V) , and for 100 kHz (fosc=10.81 MHz, Vt=0.5..0.8 V) ), using LA1787,TA7343AP, SSB osc. 450 kHz
(nBO4 ) .

Attachments: syntRDS6ssb0_1_4MHz_0.zip (/sfc/servlet.shepherd/document/download/0693l00000VHT


vdAAH)

Top

Author Posted: 29 Nov 2022 - 02:41 AM (Reply to #15) #16 0 0

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

A new version with alternative band switch for FM/AM/SSB and with encoder

Attachments: syntRDS11ssb014_17.2MHz128mem_testEncod2 (/sfc/servlet.shepherd/document/downl


oad/0693l00000VsfRUAAZ)

Top

Author Posted: 29 Nov 2022 - 03:35 AM #17 0 0

Last Updated: 30 Dec 2023 - 09:56 PM (Reply to #16)

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

My modules (for example, for test Fmax of the LC72131 and LM7001 , but for other toools, for example for
AM/FM probe tool ) with examples of the modules with some SIO control methods (may be not ready, with
bugs ).

Attachments: pll72131_10 (/sfc/servlet.shepherd/document/download/0693l00000WQCIqAAP), pll7213


1_10_3 (/sfc/servlet.shepherd/document/download/069V4000000OxmvIAC), plltestlc72131 (/sfc/servlet.she
pherd/document/download/0693l00000VsfhmAAB), testtool (/sfc/servlet.shepherd/document/download/0
69V4000000OjnBIAS), pll7001 (/sfc/servlet.shepherd/document/download/0693l00000VsfhrAAB)

Top

Author Posted: 29 Nov 2022 - 04:15 AM (Reply to #16) #18 0 0


rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

A counter, ROM and a switch in te circuit are for encoder signals emulating(only for the emulator, connect
the rotary encoder to the PD0,PD1,GND with two pull-up resistors)..

Top

Author Posted: 30 Dec 2023 - 07:46 AM #19 0 0

Last Updated: 31 Dec 2023 - 05:14 PM (Reply to #18)

rpz3598
Level: Hangaround
Joined: 24 Nov 2017
Posts: 249 View Posts

A PLL probe device with ATMEGA8A, LC72131 +band decoder , VCOs, divider by10, LF oscillator and amplifier
. It is possible to add the frequency sweep mode with step option.

Attachments: pll72131_10_sweep (/sfc/servlet.shepherd/document/download/069V4000000PFS6IAO), I


MG_20231230_060842 (/sfc/servlet.shepherd/document/download/069V4000000Ok4vIAC), testtool (/sfc/se
rvlet.shepherd/document/download/069V4000000OjyTIAS)

Top

Jump To: --megaAVR and tinyAVR

Privacy (https://www.microchip.com/en-us/about/legal-information/privacy-policy) Contact (/s/contact-us)

Site Use Terms (https://www.microchip.com/en-us/about/legal-information/website-terms-and-conditions)

Cookies (https://www.microchip.com/en-us/about/legal-information/microchip-cookie-statement)

2024 Microchip Technology Inc.

You might also like