View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jul 14, 2014 10:47 am |
|
|
Seriously nobody is going to waste the time to wade through dozens of undocumented bit I/O operations.
Use the C functions.
I doubt if the code would be even 1/5 the length written in CCS.
If you want to write 'assembler in C', then write in assembler and go to an assembler forum. |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Mon Jul 14, 2014 10:59 am |
|
|
Sorry, I don't know how to use many functions yet.
I want timer1 running all time, and when I press the button, MCU has to wake up, ON a led, and write current timer in the memory. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jul 14, 2014 11:52 am |
|
|
'write to memory'. EEPROM?. If so, then this is the delay. Takes typically 4mSec/byte. |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Mon Jul 14, 2014 12:14 pm |
|
|
Yes, timer log is written to external SPI flash.
I don't think writing to memory is the issue. First: ON Led, Second: Copy to memory.
If I disable timer1 during sleep, it wakes-up very fast, and it writes to memory too. ( but wrong time ).
I want the LED to ON inmediately after I press the button.
Now I have the feel "Did I press the button?" because it takes almost 1 second to ON after pressing the button.
The issue is clear: it is taking long to wake-up because of timer1. |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Tue Jul 15, 2014 3:31 am |
|
|
Clear code:
Code: |
#define USB_HW_CCS_16F1459
#include <16LF1459.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses MCLR
#fuses PUT
#fuses NOWDT
#use delay(int=8MHz)
#include <usb_cdc.h> // USB library
//#use rs232(baud=9600,parity=N,xmit=PIN_A4,rcv=PIN_A1,bits=8,stream=PORT2,errors)
//#use rs232(baud=9600,parity=N,xmit=PIN_C0,rcv=PIN_C1,bits=8,stream=PORT2,errors)
#define HW_ADC_PORTS sAN11
#define HW_INIT() setup_adc_ports(HW_ADC_PORTS); setup_comparator(NC_NC_NC_NC)
#include <stdlib.h>
#define LED1 PIN_C5
// SPI memory opeartions
//timer1 works on every 2 seconds
#int_TIMER1
void TIMER1_isr(void)
{
second=second+2;
time_sleep++;
time_sleep++;
if(second>=60)
{
second=second-60;
minute++;
if(minute>59)
{
minute=0;
hour++;
if(hour>23)
{
hour=0;
day++;
}
}
}
//set_timer1(32768);
}
#int_rb
void RB_ISR(void)
{
kll=input_b();
INTCONRABIE=0;
flag_button_press=1;
}
void main() {
output_bit(LED1,1);
delay_ms(10);
output_bit(LED1,0);
set_tris_a(0x07);
SDO_TRIS=0;
SDI_TRIS=0;
SCK_TRIS=0;
output_bit(CS,0);
setup_spi(SPI_MASTER|SPI_MODE_0_0|SPI_CLK_DIV_16); //SPI_CLK_DIV_64
SPIFlashInit();
init_main();
ANSELC0=0;
ANSELC1=0;
output_bit(LED1,0);
set_timer1(T1_EXTERNAL|T1_DIV_BY_1,32768);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
output_bit(LED1,0);
setup_adc( ADC_OFF );
// for power reducing
SDO_TRIS=0;
SCK_TRIS=0;
SPI_DO = 0;
SPI_SCK = 0;
output_bit(PIN_B4,0);
output_bit(PIN_B6,0);
output_c(0x00);
//sleep();
output_bit(CS,1);
while(1)
{
while(input(BUTTON)==1)
{
if(time_sleep>=2) //30
{
USBEN=0; // disable USB
output_bit(LED1,0);
//setup_oscillator(OSC_2MHZ|OSC_INTRC);
flag_osc_switch=1;
SDO_TRIS=0;
SCK_TRIS=0;
SPI_DO = 0;
SPI_SCK = 0;
output_bit(PIN_B4,0);
output_bit(PIN_B6,0);
output_c(0x00);
output_bit(CS,1);
enable_interrupt(INT_RB7);
flag_button_press=0;
above345:
SLEEP();
if(flag_button_press==0) // if wake up from timer1 goe back to sleep again
{
goto above345;
}
time_sleep=0;
count_ms=0;
disable_interrupt(INT_RB7);
}
}
if(input(BUTTON)==0)
{
output_bit(LED1,1);
// add time here
arr_value[0]=day;
arr_value[1]=hour;
arr_value[2]=minute;
arr_value[3]=second;
log_time_fn ();
output_bit(LED1,0);
time_sleep=10;
}
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Jul 15, 2014 4:40 am |
|
|
A slight improvement.
At one company I used to work for all code was rejected, if it didn't have at least 50% remarks, explaining what it was meant to do.
However one little thing leaps out, that might cause a major problem.
You should never have something like a 'test' instruction, immediately following sleep. The instruction after a sleep, is 'pre-fetched' when you go to sleep, and a test will return the status it had _before_ sleeping.
Code should be:
Code: |
do
{
sleep();
delay_cycles(1); //this is now the pre-fetched instruction 'NOP'.
}
while (flag_button_press==FALSE); // if button not pressed sleep again
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Tue Jul 15, 2014 5:05 am |
|
|
You seem to have a LOT of variables you use without first declaring them at the beginning of your program.I've always been told that can be a big problem.
Also you should indent all your conditional code to make it easier to read and follow.You could easily have more code in a section than you think!
As pointed out add comments! They're free and will help you tomoorow or next week when YOU try to figure out WHAT was this for, WHY did I do that! It also helps us help you !!While some code is obvious(at least to you) it isn't to us. When coding assembler EVERY line of code I had a comment on the end,even the obvious.
And, as a general 'debugging' comment, normally you delete everything EXCEPT the 'problem' code to eliminate possible problems. In your case get rid of the ADC stuff, SPI, USB, etc. so that ONLY the 'sleep' section remains.
hth
jay |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Tue Jul 15, 2014 5:19 am |
|
|
Thanks very much for your replies. I will work more on the code.
But the main problem is still there, timer1 interrupts still making mcu to wake up slow.
I want to try a new idea, use 1mhz crystal instead of 32khz... |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Wed Jul 16, 2014 4:50 am |
|
|
I tested with 1mhz and 2mhz crystals, but it doesn't work. I think timer1 can only work with 32khz crystal.
I'm starting to think that I made a big mistake choosing this PIC without interrupt preference... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Wed Jul 16, 2014 5:15 am |
|
|
NO, the timer1 will work with other crystal frequencies, just check the datasheet.The timer1 'subsystem' is kind of 'generic' to most PICs and while I don't use the 1459 I don't see anything in the datasheet that says '32KHZ only'.
However you will have to use the proper caps for the xtal you choose...
AND
...edit your timer1 setup to obtain your desired interrupt rate.
hth
jay |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Wed Jul 16, 2014 6:24 am |
|
|
I don't know why it is not working, I tried with 10pF and 27pF load caps. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Wed Jul 16, 2014 7:59 am |
|
|
Please show us your current code.
Perhaps you've selected the internal 32KHz osc instead of external ?
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Wed Jul 16, 2014 8:38 am |
|
|
Problem is that he is insisting on using individual register accesses, rather than the CCS functions, with no comments on the accesses. So to work out what is being done wrong, would require going through the data sheet 'line by line'.
Changing the timer crystal frequency won't change the delays, unless he is doing something like clocking the CPU off the timer. However without looking at every bit, it is impossible to work out what he is actually doing wrong.
One thing I do notice, is that he is loading the USB CDC driver at the head of the code. You can't put a chip with USB running to 'sleep', without first asking the host system to suspend the device. He doesn't then appear to actually start the USB, but it will affect how the interrupts are set-up. As has been already pointed out _simplify_.
The timer1 oscillator _won't_ run off a 1Mhz crystal. The timer itself, can _count_ a much higher frequency, but the oscillator is only rated to run watch type crystals. Quote from the data sheet:
"A dedicated low-power 32.768 kHz oscillator circuit is
built-in between pins T1OSI (input) and T1OSO
(amplifier output). This internal circuit is to be used in
conjunction with an external 32.768 kHz crystal."
Note the 32.768 kHz.
The data sheet line for the acceptable frequency for the oscillator gives the range 32.4 to 33.1 KHz. No wonder 1MHz won't run..... |
|
|
gabirelms
Joined: 28 Jun 2014 Posts: 38
|
|
Posted: Wed Jul 16, 2014 11:16 am |
|
|
Ok, I will simplify the code, no usb, no spi.
As simple as this:
Mcu sleeping all time.
Timer1 runing from external 32khz, interrupt on overflow every 2sec.
If I press button (short RB7 to gnd), mcu has to wake up and ON the led, then sleep again. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Wed Jul 16, 2014 2:36 pm |
|
|
Yes. Probably 20 lines of CCS code. |
|
|
|